欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java编程进行动态编译加载代码分享

程序员文章站 2024-02-15 19:47:52
简述 该类使用javax.tools.toolprovider自带的javacompiler进行编译,使用io的file及nio的files进行对应的路径创建、读取及拷贝...

简述

该类使用javax.tools.toolprovider自带的javacompiler进行编译,使用io的file及nio的files进行对应的路径创建、读取及拷贝,使用正则表达式进行包名与目录的转换,我只是将这些东西做了个容错整合,没什么技术含量,就为个方便吧。

模块api

class dynamicreactor://空参构造 
public class<?> dynamiccompile(string srcpath);//输入一个指定的源文件路径,若编译、拷贝成功则返回该类对应的class类实例 
private string changepackettodic(string packagename);//将一个合法的包名转换为对应javaclasspath中的路径(我是用的是eclipse 所以需要对应地增加bin这一目录,若使用其他不同编译器,请参考对应的运行上下文设置进行适当修改) 
private string getpackage(string srcpath);//由一个合法的java文件路径尝试获得其包名 

源代码

import java.io.bufferedreader;
import java.io.file;
import java.io.filereader;
import java.io.ioexception;
import java.nio.file.files;
import java.nio.file.path;
import java.nio.file.paths;
import java.nio.file.standardcopyoption;
import java.util.regex.matcher;
import java.util.regex.pattern;
import javax.tools.javacompiler;
import javax.tools.toolprovider;
/** 
 * dynamicreactor 一个动态编译模块,负责编译源文件,复制到对应包下及加载类等过程(jdk 1.7) 
 * @author 三向板砖 
 * */
public class dynamicreactor {
	javacompiler compiler;
	pattern packagepattern;
	static final string regex = "(?<=package\\s).*(?=;)";
	public dynamicreactor() 
	  {
		compiler = toolprovider.getsystemjavacompiler();
		packagepattern = pattern.compile(regex);
	}
	/** 
   * 动态编译给定源文件 
   * @param srcpath 源文件路径 
   * @return class 
   *   <br>若成功返回对应类的class实例 
   *   <br>若失败返回null 
   * */
	public class<?> dynamiccompile(string srcpath) 
	  {
		class<?> result = null;
		//获得给定路径源文件的 
		string packname = getpackage(srcpath);
		if(packname == null) 
		    {
			system.out.println("dynamicrector:load packagename error!");
			return null;
		}
		//调用compiler编译指定源文件 
		int res = compiler.run(null, null, null,srcpath);
		if(res != 0) 
		    {
			system.out.println("dynamicrector:compile java source error!");
			return null;
		}
		//获得包名对应的路径,若路径不存在则创建,若指定class文件存在则覆盖 
		string packagedst = changepackettodic(packname);
		file dstdir = new file(packagedst);
		if(!dstdir.exists()) 
		    {
			dstdir.mkdirs();
		}
		path pathfrom = paths.get(srcpath.split("\\.java")[0] + ".class");
		path pathto = paths.get(packagedst,pathfrom.getfilename().tostring());
		try {
			files.move(pathfrom, pathto, standardcopyoption.replace_existing);
		}
		catch (ioexception e) {
			system.out.println("dynamicrector:move file fail!");
			e.printstacktrace();
		}
		try {
			result = class.forname(packname+"."+pathfrom.getfilename().tostring().split("\\.class")[0]);
		}
		catch (classnotfoundexception e) {
			system.out.println("dynamicrector:class not found in final!");
		}
		return result;
	}
	//该方法将一个合法包名转化为对应路径 
	private string changepackettodic(string packagename) 
	  {
		string[] dirs = packagename.split("\\.");
		string res = ".\\bin";
		for (int i = 0;i < dirs.length;i++) 
		    {
			res += "\\"+dirs[i];
		}
		return res;
	}
	//该方法从给定的路径源文件中获得包名 
	private string getpackage(string srcpath) 
	  {
		string result = null;
		bufferedreader br;
		try {
			br = new bufferedreader(new filereader(srcpath));
			string data = br.readline();
			while(data != null) 
			      {
				if(data.indexof("package") != -1) 
				        {
					matcher m = packagepattern.matcher(data);
					if(m.find()) 
					          {
						result = m.group();
					}
					break;
				}
				data = br.readline();
			}
			br.close();
		}
		catch (ioexception e) {
			system.out.println("dynamicrector:error in open file "+srcpath);
		}
		return result;
	}
}

总结

以上就是本文关于java编程进行动态编译加载代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!