`
247687009
  • 浏览: 174510 次
  • 性别: 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();
	}


}

 

分享到:
评论

相关推荐

    java jdk1.7源码包,用于centos7使用jdk1.7编译openjdk1.8的 1.7版本

    4. **字符串中的switch语句**:允许在`switch`语句中使用字符串对象,增强了选择结构的灵活性。 5. **文件API增强**:NIO.2引入了新的文件系统API,提供了更好的文件操作能力,包括文件路径、链接、遍历目录等功能...

    关于JDK8中的字符串拼接示例详解

    总结来说,JDK 8对字符串拼接进行了优化,当字符串拼接在编译时可确定时,编译器会自动转换为使用`StringBuilder`。然而,对于运行时动态拼接的情况,开发者仍需手动使用`StringBuilder`或`StringBuffer`以获得最佳...

    传统字符串匹配以及kmp算法匹配,包含kmp 导出的Archive file 文件修改jdk可以直接运行

    在IT领域,字符串匹配是数据处理中的一个基本问题,它广泛应用于搜索引擎、文本编辑器、病毒扫描等场景。本文将深入探讨传统的字符串匹配方法以及KMP(Knuth-Morris-Pratt)算法,并结合提供的"DemoZwb"压缩包文件,...

    动态生成、编译、运行java文件

    Java的JDK提供了一个名为`javac`的命令行工具用于编译Java源文件。然而,在程序运行时,我们不能直接调用这个命令行工具。为此,Java提供了Java Compiler API(javax.tools包),允许我们在程序中动态地编译Java源...

    JDK1.6下的Base64解决方式.txt.zip

    接着,我们用`Base64.decodeBase64()`方法对编码后的字符串进行解码,还原成原始的字节数组,并再次转换回字符串。 除了Apache Commons Codec,还有其他第三方库如Google的Guava库也提供了Base64操作,但在这里,...

    JavaJDK1.7chm中文版

    4. **开关语句(Switch)支持字符串**: 除了整型、字符型,Java 7开始允许在switch语句中使用字符串对象。 5. **文件系统API增强**: 引入了`java.nio.file`包,提供了新的文件操作API,包括路径操作、文件系统查询、...

    详解Java字符串在内存中的存储位置

    通过上面的实验和分析,我们可以看到Java字符串在内存中的存储位置随着JDK版本的变化而变化。在JDK6中,字符串存储在方法区中的常量池中,在JDK7中,字符串存储在堆中,在JDK8中,字符串可能存储在堆中。 Java字符...

    java 开发工具 jdk 1.4 免安装版

    3. **正则表达式**:Java 1.4引入了`java.util.regex`包,支持正则表达式的编译和匹配,方便进行字符串的模式查找、替换和分割。 4. **集合框架的改进**:包括`TreeMap`和`TreeSet`的性能提升,以及`HashMap`和`...

    Java JDK 7学习笔记 PDF

    6. **字符串拼接优化**:JDK 7对字符串拼接进行了优化,使用StringBuilder或StringBuffer时,如果拼接的对象是字符串常量,编译器会自动优化为使用`+`操作符,避免了不必要的对象创建。 7. **动态语言支持**:JDK 7...

    java-jdk8 和java-jdk11

    Java JDK 8与Java JDK 11是两个重要的Java开发工具包,主要为开发者提供运行和编译Java应用程序所需的环境。这两个版本都是64位的,适用于处理大量内存的复杂应用。在这里,我们将深入探讨这两个版本的主要特性、...

    Java JDK11_for_Mac

    3. **文本块**:新增了文本块(Text Blocks)语法特性,用于方便地处理多行字符串,减少转义字符的使用,提升代码可读性。 4. **局部变量类型推断**:通过`var`关键字,JDK11引入了局部变量类型推断,允许编译器...

    java jdk 1.5 API html

    Java JDK 1.5,也被称为Java 5.0,是Java开发工具包的一个重要版本,于2004年发布。这个版本引入了大量的新特性,优化和改进,极大地提升了Java编程的效率和灵活性。本API HTML文档是开发者学习和查阅Java 1.5 API的...

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

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

    java jdk1.7.0_79

    Java JDK 1.7.0_79是Oracle公司发布的Java Development Kit的一个重要版本,它为Java程序员提供了必要的工具和库,以便进行Java应用程序的开发、编译、调试和运行。这个版本尤其对那些需要在Java 7环境下工作的...

    jdk11 java11 linux版 jdk-11.0.2_linux-x64_bin.tar.zip

    - **改进的字符串处理**:包括对`String`类的优化,如`lines()`方法,用于按行分割字符串,以及`strip()`和`stripIndent()`方法,用于去除字符串两侧的空白字符。 2. **Linux版JDK**: - Linux是流行的开源操作...

    java——jdk1.8

    此外,还引入了字符串去重复功能,减少了内存消耗。 8. **Java开发工具**:除了基本的JVM和编译器,JDK还提供了如JConsole、JVisualVM等工具,帮助开发者监控和分析Java应用程序的性能。 9. **安全性增强**:JDK ...

    Java 字符串的拼接详解

    下面我们将深入探讨Java字符串拼接的原理、性能影响以及编译器的优化策略。 首先,当我们用`+`运算符或`StringBuilder`/`StringBuffer`进行字符串拼接时,由于String的不可变性,每次拼接都会创建新的字符串对象。...

    jdk1.7 java官网正式版Windows 64位-jdk-7u80-windows-x64.exe

    此外,JDK 1.7还增强了字符串处理,引入了`String.join()`方法,用于连接多个字符串,以及`String.copyValueOf(char[])`,提供了一种创建字符串副本的新方式。在集合框架中,`Collections.addAll()`方法允许一次性向...

    java JDK11 版本安装包

    4. **文本块(Text Blocks, JEP 329)**:在Java中处理多行字符串变得更加简单,减少了转义字符的使用。 5. **本地变量类型推断(var关键字,JEP 286)**:在局部变量声明时,可以使用`var`关键字让编译器自动推断...

Global site tag (gtag.js) - Google Analytics