JAVA动态编译辅助类
一、场景
平时我们学学用到在JVM运行时,动态编译.java的源代码情况,比如作为灵活的配置文件。这时候就要用到动态编译,参考下列。
二、类内容
1、引入依赖:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2、编写基本类,让它继承 SimpleJavaFileObject 类。
package com.songxingzhu.utils.compile; import javax.tools.SimpleJavaFileObject;
import java.net.URI; public class JavaSourceFromCodeString extends SimpleJavaFileObject {
final String code; public JavaSourceFromCodeString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
} public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return this.code;
}
}
2、编写工具类
package com.songxingzhu.utils.context;
import java.io.File;
public class AppContext {
public static String baseDirectory() {
try {
String path = ClassLoader.getSystemResource("").getPath();
if (path==null||"".equal(path))
return getProjectPath();
return path;
} catch (Exception ignored) {
}
return getProjectPath();
}
private static String getProjectPath() {
java.net.URL url = AppContext.class.getProtectionDomain().getCodeSource()
.getLocation();
String filePath = null;
try {
filePath = java.net.URLDecoder.decode(url.getPath(), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
if (filePath.endsWith(".jar"))
filePath = filePath.substring(0, filePath.lastIndexOf(File.separatorChar) + 1);
java.io.File file = new java.io.File(filePath);
filePath = file.getAbsolutePath();
return filePath;
}
}
package com.songxingzhu.utils.compile; import org.apache.commons.io.FileUtils;
import com.songxingzhu.utils.context.AppContext; import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List; public class ClassBuilder { public static Class<?> buildClass(String fullClassName, String codeFilePath) throws IOException, ClassNotFoundException { return buildClass(fullClassName, codeFilePath, "UTF-8", AppContext.baseDirectory());
} public static Class<?> buildClass(String fullClassName, String codeFilePath, String charsetName, String buildOutput) throws IOException, ClassNotFoundException {
try {
String code = FileUtils.readFileToString(FileUtils.getFile(codeFilePath), charsetName);
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
List<JavaFileObject> files = new ArrayList<>();
files.add(new JavaSourceFromCodeString(fullClassName, code));
List<String> options = new ArrayList<>();
options.add("-classpath");
StringBuilder sb = new StringBuilder();
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
for (URL url : urlClassLoader.getURLs()) {
sb.append(url.getFile()).append(File.pathSeparator);
}
options.add(sb.toString());
options.add("-d");
options.add(buildOutput);
// execute the compiler
boolean isok = compiler.getTask(null, fileManager, null, options, null, files).call();
if (isok) {
File root = new File(buildOutput);
if (!root.exists()) root.mkdirs();
URL[] urls = new URL[]{root.toURI().toURL()};
ClassLoader classLoader = ClassBuilder.class.getClassLoader();
Class<?> clazz = Class.forName(fullClassName, true, classLoader);
return clazz;
}
return null;
} catch (Exception ex) {
throw ex;
}
}
}
JAVA动态编译辅助类的更多相关文章
- java动态编译笔记
1 前言 Java的动态编译知识,真真在实际开发中并不是经常遇到.但是学习java动态编译有助于我们从更深一层次去了解java.对掌握jdk的动态代理模式,这样我们在学习其他一些开源框架的时候就能够知 ...
- java动态编译 (java在线执行代码后端实现原理)(二)
在上一篇java动态编译 (java在线执行代码后端实现原理(一))文章中实现了 字符串编译成字节码,然后通过反射来运行代码的demo.这一篇文章提供一个如何防止死循环的代码占用cpu的问题. 思路: ...
- java动态编译 (java在线执行代码后端实现原理)
需求:要实现一个web网页中输入java代码,然后能知道编译结果以及执行结果 类似于菜鸟java在线工具的效果:https://c.runoob.com/compile/10 刚开始从什么概念都没有到 ...
- Java动态编译技术原理
这里介绍Java动态编译技术原理! 编译,一般来说就是将源代码转换成机器码的过程,比如在C语言中中,将C语言源代码编译成a.out,,但是在Java中的理解可能有点不同,编译指的是将java 源代码转 ...
- Java 动态编译--DynamicCompiler
java 动态编译自己写过程的机会比较少,记录一下: package com.xzlf.dynamicCompile; import java.io.IOException; import java. ...
- (转载)JAVA动态编译--字节代码的操纵
在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...
- Java动态编译
程序产生过程 下图展示了从源代码到可运行程序的过程,正常情况下先编译(明文源码到字节码),后执行(JVM加载字节码,获得类模板,实例化,方法使用).本文来探索下当程序已经开始执行,但在.class甚至 ...
- java动态编译类文件并加载到内存中
如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270 ...
- Java 动态编译组件 & 类动态加载
1.JDK6 动态编译组件 Java SE 6 之后自身集成了运行时编译的组件:javax.tools,存放在 tools.jar 包里,可以实现 Java 源代码编译,帮助扩展静态应用程序.该包中提 ...
随机推荐
- Oracle 导入导出 dmp 文件
导入dmp文件,需要知道这个dmp文件创建的用户.因此需要先创建用户,并授权给它. (1)用户的创建 首先,以system用户登录Oracle SQL Developer 其次,在sql工作表(可以用 ...
- Java CMYK图片转RGB图片(TwelveMonkeys方式)
TwelveMonkeys的使用比较简单,只要把相关的jar包加入到类路径,他的类我们基本不会用到,只要使用jdk ImageIO或其上层的接口就行了.jdk的ImageIO有自动发现功能,会自动查找 ...
- 能添加图标的label
能添加图标的label 效果 源码 https://github.com/YouXianMing/UI-Component-Collection 中的 IconEdgeInsetsLabel // / ...
- PL/SQL报错:Initialization error Oracle client not properly installed
安装PL/SQL8.4后,连接数据库 提示错误Initialization error Oracle client not properly installed 解决方案: 1.下载instancec ...
- jdgui反编译+javac编译=无源文件改动代码
首先我们要知道,打包好的Java程序中都是编译好的字节码文件(*.class).这些class文件会在执行的时候被载入到JVM中. 若想替换掉某一个类,那么仅仅须要将该类的源代码又一次编译然后再替换之 ...
- Android 类加载原理 和热修复——深入浅出原理与实现
一.简述 热修复无疑是这2年较火的新技术,是作为安卓工程师必学的技能之一.在热修复出现之前,一个已经上线的app中如果出现了bug,即使是一个非常小的bug,不及时更新的话有可能存在风险,若要及时更新 ...
- linux批量改名
rename 's/abc/xyz/' * 把包含abc的文件名,替换为xyz
- AsyncTask和Handler的优缺点
二者的区别我就不多说了,两个东西共同点都是为了解决耗时操作的问题,主要区别在于一个流程完善,拿来就用,一个偏向自主定制,扩展性高. 这里面有个谁是轻量级,谁适合大任务的问题:http://blog.s ...
- [转]PHP与Shell交互
From : http://blog.csdn.net/houqd2012/article/details/8219199 最近想使用PHP与Sheel进行交互.PHP控制显示和高层的逻辑结构.She ...
- 【转】PHP笔试题2010年
From : http://www.51projob.com/a/PHP/20120905/602.html 下午,还有一场比较大的面试等着我[虽然接到pps的录用电话,可是心里还是想去verycd试 ...