java内存动态编译_java动态编译类文件并加载到内存中

packagecom.basic.core.classloader;importcom.basic.core.util.FileUtil;importsun.tools.jar.Main;importjavax.tools.JavaCompiler;importjavax.tools.ToolProvider;import java.io.*;importjava.nio.file.Files;importjava.nio.file.Paths;/*** desc:自定义的类加载器,用于实现类的动态加载*/

public class MyClassLoader extendsClassLoader {//类路径

private staticString classPath ;private staticString jarPrefix;private staticStringBuilder jarAbsolutePath;static{

classPath= MyClassLoader.class.getClassLoader().getResource("").getPath();

classPath= !classPath.startsWith("/")?classPath:classPath.substring(1);//去掉开始位置的/

classPath = classPath.endsWith(File.separator)?classPath:classPath+File.separator;

jarPrefix= classPath.substring(0,classPath.lastIndexOf("classes"))+File.separator+"lib"+File.separator;

jarAbsolutePath= newStringBuilder().append(jarPrefix)

.append("hibernate-core-4.2.0.Final.jar;")

.append(jarPrefix).append("hibernate-jpa-2.0-api-1.0.1.Final.jar;")

.append(jarPrefix).append("validation-api-1.0.0.GA.jar;");

}/*** 如果父的类加载器中都找不到name指定的类,

* 就会调用这个方法去从磁盘上加载一个类

*@paramname 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java

*@return*@throwsjava.io.IOException*/@Overrideprotected Class> findClass(String name) throwsClassNotFoundException {byte[] classBytes = null;

Class> clazz = null;try{//加载类的字节码

classBytes =loadClassBytes(name);//将字节码交给JVM

clazz = defineClass(name,classBytes,0,classBytes.length);if(clazz == null){throw newClassNotFoundException(name);

}

}catch(IOException e) {

e.printStackTrace();

}returnclazz;

}/*** 加载类的字节码

*@paramname 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java

*@return*@throwsjava.io.IOException*/

private byte[] loadClassBytes(String name) throwsIOException {

String classPackageName= name.replace(".",File.separator)+".class";

String classAbsolutePath= classPath+classPackageName;//编译java文件

javac(name);byte[] bytes =Files.readAllBytes(Paths.get(classAbsolutePath));returnbytes;

}/*** 指定的类的class是否存在

*@paramname

*@return*@throwsIOException*/

public static boolean isClassExist(String name) throwsIOException {

String classPackageName= name.replace(".",File.separator)+".class";return FileUtil.isExists(classPath+classPackageName)?true:false;

}/*** 指定的类是否存在

*@paramname

*@return*@throwsIOException*/

public static boolean isJavaExist(String name) throwsIOException {

String classPackageName= name.replace(".",File.separator)+".java";return FileUtil.isExists(classPath+classPackageName)?true:false;

}/*** 编译java类

* 使用Runtime执行javac命令

*@paramname 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java

*@throwsjava.io.IOException*/

public static void javac(String name) throwsIOException {

String javaPackageName= name.replace(".",File.separator)+".java";

String javaAbsolutePath= classPath+javaPackageName;

Process process= Runtime.getRuntime().exec("javac -classpath "+ jarAbsolutePath+ " " +javaAbsolutePath);try{

InputStream errorStream=process.getErrorStream();

InputStreamReader inputStreamReader= newInputStreamReader(errorStream);

BufferedReader bufferedReader= newBufferedReader(inputStreamReader);

String line= null;while ((line=bufferedReader.readLine()) != null){

System.out.println(line);

}int exitVal =process.waitFor();

System.out.println("Process exitValue: " +exitVal);

}catch(InterruptedException e) {

e.printStackTrace();

}

}/*** 编译java类

* 使用rt.jar中的javax.tools包提供的编译器

*@paramname 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java

*@throwsjava.io.IOException*/

public static void compiler(String name) throwsIOException {

String javaPackageName= name.replace(".",File.separator)+".java";

String javaAbsolutePath= classPath+javaPackageName;

JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();

compiler.run(null,null,null,"-encoding","UTF-8","-classpath",jarAbsolutePath.toString(),javaAbsolutePath);

}/*** 动态编译一个java源文件并加载编译生成的class

*@paramname 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java

*@throwsjava.io.IOException*/

public static Class> dynamicLoadClass(String name) throwsIOException, ClassNotFoundException {if (!isClassExist(name)){

compiler(name);

}if(isJavaExist(name)){if(!FileUtil.destroyFile(classPath + name.replace(".",File.separator)+".java")){

System.out.println("========================================>>>>删除源文件失败!");

}

}returnClass.forName(name);

}public static voidmain (String[] args){

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值