Java动态编译JavaCompiler

一、tools.jar问题:

Java在进行动态编译的时候需要用到tools.jar资源包,此包在jdk\lib目录中。若tools.jar不存在则会出现进行编译时提示空指针异常:

对于缺少jar包,首先想到的解决办法是找到需要的jar包并且将其加入到buildpath,但是我们发现只是将tools.jar加入到java buildpath中仍然会出现空指针异常。后来经过查询相关资料,java在运行时使用的目录是jre,所以我们将tools.jar从jdk目录中复制一份到jre目录中即可,并且也不需要在java的buildpath中加入tools.jar

二、动态编译:

首先建立一个De.java文件:

public class De{
	public static void main(String[] args){
		System.out.println("hello world");
	}
}

 

在此处使用的是JavaCompiler进行动态编译:

compiler.run()运行后会对所指定路径的java文件进行编译,并且返回一个int类型的值。若result为0则编译成功,会在.java文件所在路径下生成.class文件

三、反射机制运行:

1、首先构建文件的目录url地址,

2、使用URLClassLoader对象的loadClass方法加载对应类

3、获取所加载类的方法

4、传入方法所需的参数通过invoke运行方法

Tips:

1、在构建URL时候一定要是URL数组。因为new URLClassLoader() 只支持URL[]的参数

2、 在使用loader.loadClass()时,传入的为类名,不要加.class后缀

3、在使用Method对象的getDeclaredMethod()方法时候第一个参数为获取方法的名字,第二个参数为本方法传入参数的类型

4、执行invoke()方法时,第一个参数为方法的返回类型。第二个参数为一个对象,例如main方法中的String[] args,它本身是一个数组,若不将其强制转换为Object,会产生异常:

 

完整代码:
 

package com.xm.demo;
 
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
 
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
/**
 * 
* @ClassName: Test 
* @Description: 动态编译运行的测试(这里用一句话描述这个类的作用) 
* @author xiaomu 
* @date 2018年1月5日 上午8:37:04 
*
 */
//将所有警告取消
@SuppressWarnings("all")
public class Test {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
	JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
	int result = compiler.run(null, null, null, "G:/demo/De.java");
	System.out.println(result==0?"成功":"失败");
	
	
	URL[] urls = new URL[] {new URL("file:/"+"G:/demo/")};
	URLClassLoader loader = new URLClassLoader(urls);
	Class c = loader.loadClass("De");
	Method m = c.getDeclaredMethod("main", String[].class);
	//通过Object把数组转化为参数
	m.invoke(null, new String[] {});
	
}
}

测试:

package DynamicCompile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class testJavaCompiler {

	public static void main(String[] args) throws IOException {
		//动态编译
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		int result = compiler.run(null, null, null, "C:\\Users\\lenovo\\Desktop\\hello.java");
		System.out.println(result==0?"编译成功":"编译失败");
		
		//动态运行
//		Runtime run = Runtime.getRuntime();
//		Process process = run.exec("java -cp C:\\Users\\lenovo\\Desktop  hello");
//		
//		InputStream in = process.getInputStream();
//		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
//		String info = "";
//		while((info=reader.readLine()) != null) {
//			System.out.println(info);
//		}
		
		try {
			URL[] urls = new URL[] {new URL("file:/" + "C:\\Users\\lenovo\\Desktop\\")};
			URLClassLoader loader = new URLClassLoader(urls);
			Class c = loader.loadClass(""
					+ "");
			//调用加载类的main方法
			Method m = c.getMethod("main", String[].class);
			
			//下面编译成m.invoke(null, "aa", "bb");会发生参数不匹配
//			m.invoke(null, new String[]{"aa", "bb"});
			//为了避免上面的问题,必须要加上(Object)强制转型
			m.invoke(null, (Object)new String[]{});
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金州饿霸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值