使用JDK动态编译java字符串_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 使用JDK动态编译java字符串

使用JDK动态编译java字符串

 2015/1/13 16:12:01  247687009  程序员俱乐部  我要评论(0)
  • 摘要:packageorg.soa.quartz.api.impl;importjava.io.File;importjava.io.FileFilter;importjava.io.FileWriter;importjava.io.IOException;importjava.lang.reflect.Method;importjava.net.URL;importjava.net.URLClassLoader;importjava.util.Arrays;importjava.util
  • 标签:使用 编译 jdk Java 字符串
class="java">package org.soa.quartz.api.impl;

import java.io.File;
import java.io.FileFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Stack;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import org.quartz.Job;
import org.quartz.JobExecutionException;
import org.soa.logger.SoaLogger;
import org.soa.quartz.core.QuartzManger;


public enum JdkCompiler   {
	INSTA;
	public final String basePath = System.getProperty("user.dir")+File.separator+"src";
	
	public void compile(java.util.List<String> list,java.util.List<String> list2){
		for(int i=0;i<list.size();i++){
			this.compile(list.get(i), list2.get(i));
		}
	}
	
	public void compile(String code,String className){
		
		String pack = "";
		final String[] split = className.split("\\.");
		String clazz = split[split.length-1];
		for(int i=0;i<split.length-1;i++){
			pack+=split[i]+File.separator;
		}
		
	    String filePath = basePath+File.separator+pack;  
	    File f = new File(filePath);  
	    if(!f.exists())
	    	f.mkdirs();
	    
	    final String pathname = filePath+clazz+".java";
		f = new File(pathname);
		try (FileWriter fw = new FileWriter(f);){
			fw.write(code);
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	      
	    //获取jdk编译器  
	    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
	    StandardJavaFileManager fileMgr = null;
	    try{
	    	fileMgr = compiler.getStandardFileManager(null, null, null);  
	        final Iterable<? extends JavaFileObject> javaFileObjects = fileMgr.getJavaFileObjects(pathname);  
		    //编译
		    compiler.getTask(null, fileMgr, null, null, null, javaFileObjects).call();  
	    }catch (Exception e) {
	    	throw new RuntimeException("编译失败");
		}finally{
			if(fileMgr!=null)
				try {
					fileMgr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	
	
	public  void loadClass(){
		try {
			 // 例如/usr/java/classes下有一个test.App类,则/usr/java/classes即这个类的根路径,而.class文件的实际位置是/usr/java/classes/test/App.class
			 File clazzPath = new File(basePath);
			 // 记录加载.class文件的数量
			 int clazzCount = 0;
			 if (clazzPath.exists() && clazzPath.isDirectory()) {
			 	// 获取路径长度
			 	int clazzPathLen = clazzPath.getAbsolutePath().length() + 1;

			 	Stack<File> stack = new Stack<>();
			 	stack.push(clazzPath);

			 	// 遍历类路径
			 	while (stack.isEmpty() == false) {
			 		File path = stack.pop();
			 		File[] classFiles = path.listFiles(new FileFilter() {
			 			public boolean accept(File pathname) {
			 				return pathname.isDirectory() || pathname.getName().endsWith(".class");
			 			}
			 		});
			 		
			 		for (File subFile : classFiles) {
			 			if (subFile.isDirectory()) {
			 				stack.push(subFile);
			 			} else {
			 				if (clazzCount++ == 0) {
			 					Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
			 					boolean accessible = method.isAccessible();
			 					try {
			 						if (accessible == false) {
			 							method.setAccessible(true);
			 						}
			 						// 设置类加载器
			 						URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
			 						// 将当前类路径加入到类加载器 强制将累加入当前classpath中
			 						method.invoke(classLoader, clazzPath.toURI().toURL());
			 					} finally {
			 						method.setAccessible(accessible);
			 					}
			 				}
			 				// 文件名称
			 				String className = subFile.getAbsolutePath();
			 				className = className.substring(clazzPathLen, className.length() - 6);
			 				className = className.replace(File.separatorChar, '.');
			 				// 加载Class类
			 				SoaLogger.debug(QuartzManger.class,"动态加载[class:{"+className+"}]");
			 			}
			 		}
			 	}
			 } 
		} catch (Exception e) {
		}
	}
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, JobExecutionException {
		String src = "package org.soa.quartz.api.job;"+
"public class Job5 implements org.quartz.Job {"+
"public void execute(org.quartz.JobExecutionContext context)"+
		"throws org.quartz.JobExecutionException {"+
		"System.out.println(\"我是动态添加的jobss\");"+
"}"+
"}";
		String src2 = "package liuyi.soa.quartz.api.job;"+
				"public class Job5 implements org.quartz.Job {"+
				"public void execute(org.quartz.JobExecutionContext context)"+
				"throws org.quartz.JobExecutionException {"+
				"System.out.println(\"我是动态添加的jobss\");"+
				"}"+
				"}";
		
		final JdkCompiler jdkCompiler = JdkCompiler.INSTA;
		jdkCompiler.compile(Arrays.asList(src,src2),Arrays.asList("org.soa.quartz.api.job.Job5","liuyi.soa.quartz.api.job.Job5") );
		jdkCompiler.compile(Arrays.asList(src,src2),Arrays.asList("org.soa.quartz.api.job.Job5","liuyi.soa.quartz.api.job.Job5") );
		
		
		jdkCompiler.loadClass();
		final Job job = (Job)Class.forName("liuyi.soa.quartz.api.job.Job5").newInstance();
		final Job job5 = (Job)Class.forName("liuyi.soa.quartz.api.job.Job5").newInstance();
		job.execute(null);
		job5.execute(null);
		
//		new JdkCompiler().loadClass();
	}


}

?

上一篇: BAT布局医药电商,想动处方药这块大蛋糕 下一篇: 没有下一篇了!
发表评论
用户名: 匿名