如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270214.html

  所谓动态编译,就是在程序运行时产生java类,并编译成class文件。  

  一、这里介绍两种动态编译java文件的方式。

    第一种:使用Runtime执行javac命令

/**
* 编译java类
* 使用Runtime执行javac命令
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static void javac(String name) throws IOException {
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 = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(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();
}
}

    第二种:使用jdk自带的rt.jar中的javax.tools包提供的编译器

/**
* 编译java类
* 使用rt.jar中的javax.tools包提供的编译器
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static void compiler(String name) throws IOException {
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);
}

  二、使用Class.forName("");将class文件加载到内存中,并得到该类的class对象

/**
* 动态编译一个java源文件并加载编译生成的class
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static Class<?> dynamicLoadClass(String name) throws IOException, ClassNotFoundException {
if (!isClassExist(name)){
compiler(name);
}
if(isJavaExist(name)){
if(!FileUtil.destroyFile(classPath + name.replace(".",File.separator)+".java")){
System.out.println("========================================>>>>删除源文件失败!");
}
}
return Class.forName(name);
}

  以下是全部代码:

package com.basic.core.classloader;

import com.basic.core.util.FileUtil;
import sun.tools.jar.Main; import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths; /**
* desc:自定义的类加载器,用于实现类的动态加载
*/
public class MyClassLoader extends ClassLoader { //类路径
private static String classPath ; private static String jarPrefix; private static StringBuilder 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 = new StringBuilder().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指定的类,
* 就会调用这个方法去从磁盘上加载一个类
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @return
* @throws java.io.IOException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classBytes = null;
Class<?> clazz = null;
try {
//加载类的字节码
classBytes = loadClassBytes(name);
//将字节码交给JVM
clazz = defineClass(name,classBytes,0,classBytes.length);
if(clazz == null){
throw new ClassNotFoundException(name);
}
} catch (IOException e) {
e.printStackTrace();
}
return clazz;
} /**
* 加载类的字节码
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @return
* @throws java.io.IOException
*/
private byte[] loadClassBytes(String name) throws IOException {
String classPackageName = name.replace(".",File.separator)+".class";
String classAbsolutePath = classPath+classPackageName;
//编译java文件
javac(name);
byte[] bytes = Files.readAllBytes(Paths.get(classAbsolutePath));
return bytes;
} /**
* 指定的类的class是否存在
* @param name
* @return
* @throws IOException
*/
public static boolean isClassExist(String name) throws IOException {
String classPackageName = name.replace(".",File.separator)+".class";
return FileUtil.isExists(classPath+classPackageName)?true:false;
} /**
* 指定的类是否存在
* @param name
* @return
* @throws IOException
*/
public static boolean isJavaExist(String name) throws IOException {
String classPackageName = name.replace(".",File.separator)+".java";
return FileUtil.isExists(classPath+classPackageName)?true:false;
} /**
* 编译java类
* 使用Runtime执行javac命令
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static void javac(String name) throws IOException {
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 = new InputStreamReader(errorStream);
BufferedReader bufferedReader = new BufferedReader(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包提供的编译器
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static void compiler(String name) throws IOException {
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
* @param name 类的全限定包名 不带后缀 例如com.test.Notice 而不要写成com.test.Notice.java
* @throws java.io.IOException
*/
public static Class<?> dynamicLoadClass(String name) throws IOException, ClassNotFoundException {
if (!isClassExist(name)){
compiler(name);
}
if(isJavaExist(name)){
if(!FileUtil.destroyFile(classPath + name.replace(".",File.separator)+".java")){
System.out.println("========================================>>>>删除源文件失败!");
}
}
return Class.forName(name);
} public static void main (String[] args){ } }

  

 

java动态编译类文件并加载到内存中的更多相关文章

  1. linux函数深入探索——open函数打开文件是否将文件内容加载到内存空间

    转自:https://blog.csdn.net/qq_17019203/article/details/85051627 问题:open(2)函数打开文件是否将文件内容加载到内存空间 首先,文件打开 ...

  2. 深入浅出JVM(一):你写得.java文件是如何被加载到内存中执行的

    众所周知,.java文件需要经过编译生成.class文件才能被JVM执行. 其中,JVM是如何加载.class文件,又做了些什么呢? .class文件通过 加载->验证->准备->解 ...

  3. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  4. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  5. 想要配置文件生效 需要通过添加到web.xml加载到内存中

    想要配置文件生效 需要通过添加到web.xml加载到内存中

  6. Java_类文件及加载机制

    类文件及类加载机制 标签(空格分隔): Java 本篇博客的重点是分析JVM是如何进行类的加载的,但同时我们会捎带着说一下Class类文件结构,以便对类加载机制有更深的理解. 类文件结构 平台无关性 ...

  7. 将Xml文件递归加载到TreeView中

    #region [通过XDocument的方式将Xml文件递归到TreeView控件中] //读取Xml文件(XDocument) //1.加载Xml文件 XDocument  document=XD ...

  8. gensim Word2Vec 训练和使用(Model一定要加载到内存中,节省时间!!!)

    训练模型利用gensim.models.Word2Vec(sentences)建立词向量模型该构造函数执行了三个步骤:建立一个空的模型对象,遍历一次语料库建立词典,第二次遍历语料库建立神经网络模型可以 ...

  9. 把資源加载到内存中 BMP 出错

    BMP文件放到VS的資源中時,VS會將BMP的文件頭去掉,即BITMAPFILEHEADER,這個結構體去除.所以當加載BMP到內存中時,如果是使用GDI+或是其它解釋庫時,會解析失敗. 所以在讀取B ...

随机推荐

  1. SQLserver删除某数据库中所有表 方法 二

    方便删除数据库中所有的数据表,清空数据库,有些有约束,不能直接delete,需要先删除库中的约束,代码如下: --删除所有约束DECLARE c1 cursor for select 'alter t ...

  2. UVA 12232 Exclusive-OR(并查集+思想)

    题意:给你n个数,接着三种操作: I p v :告诉你 Xp = v I p q v :告诉你 Xp ^ Xq = v Q k p1 p2 … pk:问你k个数连续异或的结果 注意前两类操作可能会出现 ...

  3. C# 枚举(enum)

    public enum EnumStatus { On=0, Off=1 } //获取值:0 Convert.ToInt32(EnumStatus.On); //获取On EnumStatus.On; ...

  4. cf 二分图

    题目链接:http://vjudge.net/contest/133033#problem/C 题目大意:给你n个点,m条边,将其分成两个集合,集合A是图的一个点覆盖,集合B也是图的一个点覆盖,要求集 ...

  5. 利用TaskCompletionSource将EAP转换成TAP

        1.原始的异步方法的调用   我们来看个简单的例子,在这里演示调用 WebClient.DownloadStringAsync 方法(这个方法不是 TAP),然后由 WebClient.Dow ...

  6. 每天一个linux命令--退出<符号

    linux出现如下情况: [calendar@test190 logs]$ [calendar@test190 logs]$ [calendar@test190 logs]$ [calendar@te ...

  7. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 G. Garden Gathering

    Problem G. Garden Gathering Input file: standard input Output file: standard output Time limit: 3 se ...

  8. RequireJS 循环依赖报 模块undefined 处理方案

    RequireJS 循环依赖 开始学习使用RequireJS之后做了几个小例子,之后想着把手头的项目也用RequireJS写一遍试试.感觉胜利就在前方了,忽然发现始终卡在一个问题上: 很常见的一个问题 ...

  9. js中的this关键字详解

    this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, 复制代码 代码如下: function test(){ this.x = 1; ...

  10. 【POJ】3678 Katu Puzzle

    http://poj.org/problem?id=3678 题意:很幼稚的题目直接看英文题面= = #include <cstdio> #include <cstring> ...