`
247687009
  • 浏览: 171322 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用JDK动态编译java字符串

    博客分类:
  • 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();
	}


}

 

分享到:
评论

相关推荐

    支持jdk1.8的java反编译工具 luyten

    Procyon-Decompiler支持JDK1.8类的反编译,在很多方面做得非常不错:字符串的Switch、枚举声明方面、注解方面、匿名类、内部类、Java8新接口规范、Java8 Lambda表达式、Java8 方法传递等。  luyten是Procyon的GUI,...

    java jdk8 学习笔记

    2.动态加载类别文档、字符串池(String Pool)等特性为节省内存而设计 3.jdk java development kit java 开发工具集 java se 平台包括jdk与java语言 ,(不知道编程语言是什么?可以这样想 :java 语言 -&gt;类文件...

    auto-string-formatter:用于Java的字符串格式化库,在编译时通过注释处理生成优化的formatter方法

    auto-string-formatter是Java的字符串格式化库,可在编译时通过注释处理生成优化的formatter方法。 auto-string-formatter具有以下功能: 使用StringBuilder就像手写代码一样快。 (大多数)兼容String.format 。...

    java程序设计实验指导代码

    8.4 实验3 字符串的比较和查找最长子串 8.5 实验4 单词逆向输出问题 8.6 实验5 ISBN书号校验问题 第9章 Applet小应用程序 9.1 预备知识 9.2 实验1 Applet生命周期 9.3 实验2 Applet的参数提取 9.4 实验3 鼠标...

    Java JDK正则表达

     正则表达式是Java处理字符串、文本的重要工具。  Java对正则表达式的处理集中在以下两个两个类:  java.util.regex.Matcher 模式类:用来表示一个编译过的正则表达式。  java.util.regex.Pattern 匹配类...

    java学习及java学习代码.rar

    (2)分别使用JDK命令行和Eclipse编译Java Applet,并建立HTML文档运行该Applet。将字节码文件和HTML文件合并压缩生成"Applet.jar"文件。记录操作过程。 import java.awt.*; import java.applet.Applet; public class ...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    4.4.3 字符串编码 115 4.5 查询java api文件 117 4.6 重点复习 119 4.7 课后练习 120 chapter5 对象封装 125 5.1 何谓封装 126 5.1.1 封装对象初始流程 126 5.1.2 封装对象操作流程 128 5.1.3 封装...

    JVM的机制学习手册非常不错

    JVM规范中定义了class文件的格式,JDK在编译java源码时,使用了javac,javac编译的步骤: 1. 分析和输入到符号表(Parse And Enter) Parse做的是词法和语法的分析。 词法分析:将代码字符串转变为token序列 语法...

    Java开发技术大全(500个源代码).

    ArrayString.java 字符串数组 assignTwoDime.java 为二维数组赋值 getMaxElem.java 获取数组中的最大元素 incCapicity.java 演示StingBuffer的容量增长 SortDemo.java 排序示例 travelTwoDime.java 遍历二维...

    Java中高级核心知识全面解析(精华必看)

    1.2.1.字符型常量和字符串常量的区别? 1.2.2.关于注释? 1.2.3.标识符和关键字的区别是什么? 1.2.4.Java中有哪些常见的关键字? 1.2.5.自增自减运算符 1.2.6.continue、break、和return的区别是什么? 1.2.7.Java...

    jdk-11.0.19-windows-x64-bin.zip

    JDK 11引入了“var”关键字,允许根据初始化值的类型自动推断局部变量的类型,还新增了单引号字符串支持,并增强了安全性,例如默认禁用弱加密算法,更新TLS版本以保护应用程序免受安全威胁 模块化。JDK 11引入了...

    java基础常识与概念

    字符型常量和字符串常量的区别? 注释有哪几种形式? 标识符和关键字的区别是什么? Java 语言关键字有哪些? 自增自减运算符 continue、break 和 return 的区别是什么? 方法 什么是方法的返回值?方法有哪几种类型?...

    源码编译工具openoj.zip

    openoj是一个可以对从一个输入流中包括文件,网络流,字符串所代表的源代码进行编译,运行,和测试的程序。现在支持对java、c和 c 的编译和运行以及测试。 openoj是一个用maven构建的,所以可以直接在eclipse中导入...

    JAVA正则表达式--Pattern和Matcher

    java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。 它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式。 Matcher 一个Matcher对象是一个...

    基于java实现的数据库管理系统.7z

    1.执行过程思路:先根据sql语法把sql字符串切割成各个有效部分,把其相应的封装到运行时实体中, 相当于把.java编译成了.class,再读取dbf文件,执行实体对dbf文件内容进行相应的操作,相当于 类加载执行,实现sql...

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-091-Java基本语法-控制语句-switch语句-字符串作为比较对象.avi 北京动力节点-Java编程零基础教程-092-Java基本语法-控制语句-switch语句-举例1.avi 北京动力节点-Java编程零...

    java范例开发大全源代码

     实例42 字符串索引越界异常(StringIndexOutBounds) 60  实例43 操作错误(UnsupportedOperationException) 60  4.2 运行时异常 61  实例44 找不到指定类时发生的异常(ClassNotFoundException) 62 ...

    java初学者必看

    5.1.3 StringBuffer创建字符串 5.2 连接字符串 5.2.1 与字符串的连接 5.2.2 与其他数据类型的连接 5.3 String字符串操作 5.3.1 基本操作 5.3.2 比较 5.3.3 转化 5.3.4 查找 5.3.5 截取拆分 5.3.6 替换或...

    Java课程设计案例精选

     2.4 字符串  2.5 数组 第3章 类和对象  3.1 类的定义与使用  3.2 继承  3.3 重载  3.4 包与接口   3.5 Java的垃圾回收与析构  3.6 抽象类与内部类  3.7 基础类的使用  第4章 网页浏览器开发 ...

Global site tag (gtag.js) - Google Analytics