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。
相关推荐
要从Java环境中解析APK文件,通常需要特定的工具和库,本话题将详细探讨如何利用Java来解析APK,以及相关的关键知识点。 首先,我们需要理解APK的结构。一个APK文件实际上是一个ZIP格式的压缩包,包含以下几个核心...
总的来说,Java中的JSON解析jar包为我们提供了便利的数据交换手段,使我们能够轻松地处理JSON数据。理解并熟练使用这些库,可以极大地提升开发效率和项目的可维护性。在实际工作中,根据项目需求和团队成员的熟悉...
【Selenium及依赖jar包(Java)】是一个用于自动化浏览器操作的开源工具,它在Java环境中广泛使用。Selenium的核心功能在于模拟用户的行为,比如点击、输入、滚动、选择等,使得开发者能够对Web应用程序进行自动化...
Java是一种广泛使用的编程语言,尤其在企业级应用开发中占据主导地位。在处理Web服务、API交互或数据序列化时,JSON(JavaScript Object Notation)是常见...理解并掌握这些库的使用,将极大地提高开发效率和代码质量。
Java开发过程中,jar(Java Archive)包是必不可少的资源,它们包含了编译好的类文件、元数据以及其他资源,便于代码的组织和复用。本压缩包"java_常用jar包整理.rar"显然是一份集合了Java开发中常用库的资源,可以...
- **解析和加载jar包**:服务器端需要将接收到的字节流转换回jar文件,并使用Java的ClassLoader加载这个jar包。 - **执行命令**:找到jar包中的main方法,通过反射机制调用这个方法执行任务。 - **返回结果**:...
在Java开发中,jar包隔离是一个重要的议题,尤其是在大型项目或者多模块系统中。...通过理解以上知识点并应用"jar包隔离代码.zip"中的示例,开发者可以更有效地解决jar包冲突问题,提高项目的稳定性和可维护性。
Java的`CommonUtils.jar`文件是一个集合了各种通用工具方法的库,对于Java开发者来说,它极大地提高了开发效率,简化了常见的编程任务。这个库通常包含了大量的静态方法,覆盖了字符串处理、数组操作、日期时间操作...
Java开发过程中,JAR(Java Archive)包是不可或缺的一部分,它是Java平台特有的打包机制,用于收集多个类文件、相关的资源文件以及元数据到一个单一的文件中,方便部署和使用。"java初学或者高级开发JAR包全必备"这...
为了解决Java与Delphi之间的互操作性问题,出现了JarOrClass2Pas工具,它能够将Java的Jar包和Class文件转换为Delphi的Pas文件,从而实现Java代码在Delphi环境中的复用。本文将详细介绍这个工具及其工作原理。 一、...
3. **Java类加载器**:JVM如何加载并执行JAR内的类。 4. **Java集合框架**:如ArrayList、HashMap等,用于存储和操作数据。 5. **输入/输出流**:读取和写入文件,包括从JAR中读取资源。 6. **反射API**:运行时动态...
动态加载jar包技术主要涉及Java的反射机制、类加载器和插件系统。下面我们将深入探讨这些知识点。 首先,了解Java的反射机制是理解动态加载的基础。Java反射API允许我们在运行时检查类、接口、字段和方法的信息,...
`rt.jar`是Java开发中一个非常核心的文件,它包含在Java运行时环境中,是Java标准类库(Java Standard Edition, Java SE)的核心部分。这个JAR(Java Archive)文件集成了Java语言的关键功能,使得开发者能够编写出...
DOM4J和Java反射是Java开发中两个非常重要的技术,它们在处理XML文档和动态对象操作方面发挥着关键作用。在此,我们将深入探讨这两个概念及其在实现Bean与XML之间的转换中的应用。 首先,DOM4J是一个Java库,专门...
编译器和运行时系统可以使用注解来执行特定的任务,如代码验证、生成文档、持久化等。 10. **Spring框架元数据** Spring框架利用XML或Java配置元数据来定义bean的依赖关系和行为。通过`@Component`、`@Service`、`...
Java代码混淆是一种安全措施,主要用于保护Java应用程序的源代码不被未经授权的人员逆向工程解析。Allatori就是一款专门用于Java代码混淆的工具,它能够将可读性强的Java字节码转换为难以理解的形式,以此增加逆向...
`commons-beanutils.jar`库简化了JavaBean的使用,提供了对Java反射和自省API的封装,主要功能有: - 对JavaBean的属性进行便捷的读写操作,无需手动编写getter和setter方法调用。 - 能够将数据结构(如Map)转换为...
- **使用JAR**:Java程序可以通过`java -jar`命令执行JAR文件,也可以通过`jar`命令进行创建、更新和提取JAR内容。 - **MANIFEST.MF**:JAR文件中的清单文件,指定类路径、主类等信息。 - **依赖管理**:理解如何...
例如,你可以使用`java -jar AXMLPrinter2.jar your_file.xml > output.txt`这样的命令来解析XML文件。 2. **AXMLPrinter.jar**:这是AXMLPrinter的早期版本,功能与AXMLPrinter2类似,但可能在某些特性或性能上...