1、使用JarFile类读取jar包MANIFEST.MF中的Main-Class,如果没有设置Main-Class则调用方法中指定执行函数
2、解压jar文件
3、设置classPath
4、利用反射取得class和method,并运行该method
如下代码Run.java将被打包到jar文件中,使用Maven构建并打包:
package com.chenzehe.runjar; public class Run { /** * @param args */ public static void main(String[] args) { System.out.println("run......"); if (args.length > 0) { System.out.println("args: " + args[0]); } } }
开始打包没有指定在MANIFEST.MF中指定Main-Class,下面运行时只能指定要运行的类。
RunJar.java为解析并执行该jar文件方法的类:
package com.chenzehe.runjar; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; public class RunJar { /** * @param args */ public static void main(String[] args) throws Throwable { String usage = "RunJar jarFile [mainClass] args..."; if (args.length < 1) { System.err.println(usage); System.exit(-1); } int firstArg = 0; String fileName = args[firstArg++]; File file = new File(fileName); // 从jar文件MANIFEST.MF中读取Main-Class String mainClassName = null; JarFile jarFile; try { jarFile = new JarFile(fileName); } catch (IOException io) { throw new IOException("Error opening job jar: " + fileName) .initCause(io); } Manifest manifest = jarFile.getManifest(); if (manifest != null) { mainClassName = manifest.getMainAttributes().getValue("Main-Class"); } jarFile.close(); if (mainClassName == null) { if (args.length < 2) { System.err.println(usage); System.exit(-1); } // 如果MANIFEST.MF未设置Main-Class,则用户输入 mainClassName = args[firstArg++]; } mainClassName = mainClassName.replaceAll("/", "."); final File workDir = File.createTempFile("unjar", "", new File(System.getProperty("user.dir"))); workDir.delete(); workDir.mkdirs(); if (!workDir.isDirectory()) { System.err.println("Mkdirs failed to create " + workDir); System.exit(-1); } // 解压jar文件 unJar(file, workDir); // 设置classPath ArrayList<URL> classPath = new ArrayList<URL>(); classPath.add(new File(workDir + "/").toURL()); classPath.add(file.toURL()); ClassLoader loader = new URLClassLoader(classPath.toArray(new URL[0])); Thread.currentThread().setContextClassLoader(loader); // 利用反射取得class和method Class<?> mainClass = Class.forName(mainClassName, true, loader); Method main = mainClass.getMethod("main", new Class[] { Array .newInstance(String.class, 0).getClass() }); String[] newArgs = Arrays.asList(args).subList(firstArg, args.length) .toArray(new String[0]); try { // 运行方法 main.invoke(null, new Object[] { newArgs }); } catch (InvocationTargetException e) { throw e.getTargetException(); } } //解压jar包中的文件到toDir目录 public static void unJar(File jarFile, File toDir) throws IOException { JarFile jar = new JarFile(jarFile); try { Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); if (!entry.isDirectory()) { InputStream in = jar.getInputStream(entry); try { File file = new File(toDir, entry.getName()); if (!file.getParentFile().mkdirs()) { if (!file.getParentFile().isDirectory()) { throw new IOException( "Mkdirs failed to create " + file.getParentFile() .toString()); } } OutputStream out = new FileOutputStream(file); try { byte[] buffer = new byte[8192]; int i; while ((i = in.read(buffer)) != -1) { out.write(buffer, 0, i); } } finally { out.close(); } } finally { in.close(); } } } } finally { jar.close(); } } }
该代码为Hadoop中job提交到服务器调用的代码RunJar。
相关推荐
Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件. Discovery Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。. EL Commons-EL 提供在...
12反射 是java程序开发的特征之一,允许java程序对自身进行检查,并能直接操作程序的内部属性; instanceof操作符,instanceof.java; 获取类的信息,ViewClassInfoJrame.java; 动态调用类的方法,CallMetod.java; ...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
Digester基于规则的XML文档解析,主要用于XML到Java对象的映射. commons-beanutils.jar 提供对Java 反射和自省API的包装. aspectjweaver.jar 用于在Spring 2.0中集成AspectJ AspectJ LTW织入器 ognl.jar OGNL是...
JAVA 范例大全 光盘 资源 书籍目录: 前言. 第1章 开发环境搭建 1 实例1 下载、安装并配置JDK 1 实例2 第一个Java程序 3 实例3 在Eclipse中创建第一个Java程序 4 常见问题 javac不是内部或者外部命令 6 常见...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
commons-jelly 能够把XML转换成可执行代码,所以Jelly是一个基于XML与Java的脚本和处理引擎 commons-jexl 是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言 commons-jxpath 定义了一个...
全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
JsonLube用于将Json对象转成JAVA Bean对象,不同于传统在运行时进行反射的方式,JsonLube采用在编译时自动生成解析Json的代码,使用方式依然简单,然而在移动平台上却可以收获更好的性能。 使用方式 gradle配置 ...
尽管现有的 EmployeeMgmt 应用程序已经有了 Façade 接口,但这个接口是暴露给 Servlet 使用的,最好能再为 Flex 定义另一个接口 FlexService,并隐藏 Java 语言的特定对象(如 清单 1 所示): 清单 1. Flex...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
解析给定jar中所有类的字节码,自省反射调用(通过反射访问类/方法/字段等),并将其配置添加到生成的反射配置文件中。 动态剖析 作为Java代理附加到常规Java应用程序(不是来自本机映像),并拦截反射调用(还包括...