`
chenzehe
  • 浏览: 538141 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

用反射解析jar文件并执行里面Java代码

 
阅读更多

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。

下载本例代码

 

 

 

0
0
分享到:
评论

相关推荐

    Java解析apk所需jar包

    要从Java环境中解析APK文件,通常需要特定的工具和库,本话题将详细探讨如何利用Java来解析APK,以及相关的关键知识点。 首先,我们需要理解APK的结构。一个APK文件实际上是一个ZIP格式的压缩包,包含以下几个核心...

    java json解析 jar 包

    总的来说,Java中的JSON解析jar包为我们提供了便利的数据交换手段,使我们能够轻松地处理JSON数据。理解并熟练使用这些库,可以极大地提升开发效率和项目的可维护性。在实际工作中,根据项目需求和团队成员的熟悉...

    selenium及依赖jar包(java)

    【Selenium及依赖jar包(Java)】是一个用于自动化浏览器操作的开源工具,它在Java环境中广泛使用。Selenium的核心功能在于模拟用户的行为,比如点击、输入、滚动、选择等,使得开发者能够对Web应用程序进行自动化...

    java解析json的jar包

    Java是一种广泛使用的编程语言,尤其在企业级应用开发中占据主导地位。在处理Web服务、API交互或数据序列化时,JSON(JavaScript Object Notation)是常见...理解并掌握这些库的使用,将极大地提高开发效率和代码质量。

    java_常用jar包整理.rar

    Java开发过程中,jar(Java Archive)包是必不可少的资源,它们包含了编译好的类文件、元数据以及其他资源,便于代码的组织和复用。本压缩包"java_常用jar包整理.rar"显然是一份集合了Java开发中常用库的资源,可以...

    JAVA Socket远程执行任务

    - **解析和加载jar包**:服务器端需要将接收到的字节流转换回jar文件,并使用Java的ClassLoader加载这个jar包。 - **执行命令**:找到jar包中的main方法,通过反射机制调用这个方法执行任务。 - **返回结果**:...

    jar包隔离代码.zip

    在Java开发中,jar包隔离是一个重要的议题,尤其是在大型项目或者多模块系统中。...通过理解以上知识点并应用"jar包隔离代码.zip"中的示例,开发者可以更有效地解决jar包冲突问题,提高项目的稳定性和可维护性。

    Java的CommonUtils的.jar文件

    Java的`CommonUtils.jar`文件是一个集合了各种通用工具方法的库,对于Java开发者来说,它极大地提高了开发效率,简化了常见的编程任务。这个库通常包含了大量的静态方法,覆盖了字符串处理、数组操作、日期时间操作...

    java初学或者高级开发JAR包全必备

    Java开发过程中,JAR(Java Archive)包是不可或缺的一部分,它是Java平台特有的打包机制,用于收集多个类文件、相关的资源文件以及元数据到一个单一的文件中,方便部署和使用。"java初学或者高级开发JAR包全必备"这...

    JarOrClass2Pas(Java代码转Delphi)

    为了解决Java与Delphi之间的互操作性问题,出现了JarOrClass2Pas工具,它能够将Java的Jar包和Class文件转换为Delphi的Pas文件,从而实现Java代码在Delphi环境中的复用。本文将详细介绍这个工具及其工作原理。 一、...

    javaReport.zip

    3. **Java类加载器**:JVM如何加载并执行JAR内的类。 4. **Java集合框架**:如ArrayList、HashMap等,用于存储和操作数据。 5. **输入/输出流**:读取和写入文件,包括从JAR中读取资源。 6. **反射API**:运行时动态...

    java 动态加载jar包

    动态加载jar包技术主要涉及Java的反射机制、类加载器和插件系统。下面我们将深入探讨这些知识点。 首先,了解Java的反射机制是理解动态加载的基础。Java反射API允许我们在运行时检查类、接口、字段和方法的信息,...

    rt.jar java开发相关jar包

    `rt.jar`是Java开发中一个非常核心的文件,它包含在Java运行时环境中,是Java标准类库(Java Standard Edition, Java SE)的核心部分。这个JAR(Java Archive)文件集成了Java语言的关键功能,使得开发者能够编写出...

    dom4j 和java反射

    DOM4J和Java反射是Java开发中两个非常重要的技术,它们在处理XML文档和动态对象操作方面发挥着关键作用。在此,我们将深入探讨这两个概念及其在实现Bean与XML之间的转换中的应用。 首先,DOM4J是一个Java库,专门...

    java读取metadata元信息

    编译器和运行时系统可以使用注解来执行特定的任务,如代码验证、生成文档、持久化等。 10. **Spring框架元数据** Spring框架利用XML或Java配置元数据来定义bean的依赖关系和行为。通过`@Component`、`@Service`、`...

    Allatori java 代码混淆

    Java代码混淆是一种安全措施,主要用于保护Java应用程序的源代码不被未经授权的人员逆向工程解析。Allatori就是一款专门用于Java代码混淆的工具,它能够将可读性强的Java字节码转换为难以理解的形式,以此增加逆向...

    java常用扩展工具jar包详解

    `commons-beanutils.jar`库简化了JavaBean的使用,提供了对Java反射和自省API的封装,主要功能有: - 对JavaBean的属性进行便捷的读写操作,无需手动编写getter和setter方法调用。 - 能够将数据结构(如Map)转换为...

    java基础学习dom资料及jar包

    - **使用JAR**:Java程序可以通过`java -jar`命令执行JAR文件,也可以通过`jar`命令进行创建、更新和提取JAR内容。 - **MANIFEST.MF**:JAR文件中的清单文件,指定类路径、主类等信息。 - **依赖管理**:理解如何...

    AXMLPrinter2官网源码和jar文件

    例如,你可以使用`java -jar AXMLPrinter2.jar your_file.xml &gt; output.txt`这样的命令来解析XML文件。 2. **AXMLPrinter.jar**:这是AXMLPrinter的早期版本,功能与AXMLPrinter2类似,但可能在某些特性或性能上...

Global site tag (gtag.js) - Google Analytics