`

java动态编译

 
阅读更多

1.java通过getSystemJavaCompiler得到的是com.sun.tools.javac.api.JavacTool(应该吧)

 

2.如果不存在jdk的话(只安装jre),搜寻路径是System.getProperty("java.home")+lib+tools.jar;

 

3.编译时如果没有指定class生成路径,会在System.getProperty("user.dir")下生成字节码文件,如果需要指定生成路径,可以通过指定编译参数e.g:

 

String[] path = new String[]{"-d",curPath};
Iterable<String> options = Arrays.asList(path);
task = compiler.getTask(out, fileManager, null, options, null, fileObjects);
 

 

4.如果需要多次动态编译(一个虚拟机生命周期内),如果仅仅使用class.forname("xxx")会出现每次加载同一个class对象,

因为如果你没有指定类加载器,默认的当前类加载器会先检查是否已经加载过(通过类的全限定名),如果加载过,则直接返回

已经加载过的class对象,不会加载你重新编译过的class,参见如下:

 

synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                ........
                ........
                ........
            return c;

 所以,如果要每次加载重新编译过的类,两个办法,动态更改类名,采用你自己的类加载器(这里,后来看到有一个urlclassloader类加载器,不知道可行否),自己的类加载器也很简单(重写那两个方法),只需在指定的url中得到类的字节码数组(文件流的读取),参见如下

 

	/*
	 * 重写findclass方法
	 */
	public Class<?> findClass(String name){
		byte[] byteCode = loadClassData(name);
		return defineClass(name,byteCode,0,byteCode.length);
	}
	
	/*
	 * 重写loadclassdata方法
	 */
	public byte[] loadClassData(String name){
		//字节码输入流
		FileInputStream in = null;
		//字节码输出流
		ByteArrayOutputStream out = null;
		//返回的字节码数组
		byte[] byteCode = null;
		try{
			//创建流
			in = new FileInputStream(new File(path+name+".class"));
			out = new ByteArrayOutputStream();
			
			//开始加载字节码
			int c = -1;
			while((c = in.read())!=-1){
				out.write(c);
			}
			//转换字节码数组
			byteCode = out.toByteArray();
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			//关闭字节码流
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
		}
		return byteCode;
	}

 

5.这个是在测试过程中碰到的问题,在服务器的fitnesse等类似当前工作目录不是工程目录的工具或者软件中运行你的类(包含动态编译的代码),如果你指定动态编译类的路径不是绝对路径而是相对路径(比如相对你的工程),会出现找不到指定路径(你动态编译的类)。解决办法有二,如果你的应用不是跨平台或者允许在用户其他目录生成,将动态生成的类路径指定为绝对路径比如c盘根(其他windows上一定有的路径)或者home/${user}下,方法二的情况是你的项目跨平台或者不允许在用户机器或服务器上其他路径上创建文件的话,可以在你的当前运行类的目录下生成动态编译的类文件,参见如下

 

String curPath = Calculator.class.getResource("/").toString().replace("%20", " ").substring(6);

 

6.系统的user.dir不可更改,前提是当你启动jvm之后,=。=

 

分享到:
评论

相关推荐

    JavaCompiler --JDK6 API的简介(java动态编译)

    JavaCompiler --JDK6 API 的简介(java动态编译) JavaCompiler 是 Java 中的一个编译器接口,提供了编译 Java 源代码的功能。在 Java SE6 中,JavaCompiler 接口是 javax.tools 包的一部分,提供了标准的方式来...

    java动态编译指定java文件且将java文件生成jar

    在Java编程中,有时我们需要在运行时动态地编译源代码文件,并将其打包成可执行的JAR(Java Archive)文件。这样的需求通常出现在我们希望根据用户输入或特定条件生成并执行新的代码逻辑时。本教程将深入讲解如何...

    java动态编译java源文件

    Java动态编译指的是在程序运行时将Java源代码编译为字节码并加载到Java虚拟机(JVM)中的过程。这种技术在许多场景下非常有用,例如在开发环境中进行快速迭代、AOP(面向切面编程)或运行时代码生成等。Java的`javax...

    Java动态编译Java代码,运行在内存中,并执行

    添加动态执行的编译环境 options 是个集合,添加内容,字符集,classpath等 * 6.传入JavaFileObject的java文件,是个集合,创建JavaSourceObject实现这个接口,Kind.SOURCE.extension = '.java' * 7.创建任务并...

    java 动态编译.java文件,动态运行类

    在Java编程中,动态编译和运行类是一项重要的能力,特别是在需要实时更新代码或实现热部署的场景下。本文将深入探讨如何利用Java的API来动态编译.java源文件,并执行编译后的类。 首先,Java的`javac`命令行工具是...

    java动态编译 ,写了一个jsp在页面上编辑java代码,然后servlet动态编译并执行main方法

    Java动态编译是一种技术,允许程序在运行时将源代码转换为字节码并加载到JVM(Java虚拟机)中。这种能力使得Java应用程序能够根据需要编译和执行新的代码,增强了软件的灵活性和可扩展性。在给定的场景中,用户通过...

    Java 动态编译源码并调用

    Java 动态编译源码并调用是Java开发中的一种高级技巧,它允许程序在运行时根据需要编译和执行新的代码。这种能力在某些场景下非常有用,例如插件系统、元编程或者在运行时自动生成和执行特定逻辑。下面我们将详细...

    java 动态编译打包 动态编译可以用于实现动态代码生成、动态加载、插件化等功能

    Java 动态编译打包是Java开发中的一个重要技术,它允许程序在运行时生成和编译源代码,然后即时加载到应用程序中。这种技术在许多场景下都非常有用,例如实现动态代码生成、动态加载和插件化系统。下面将详细讨论...

    Java 动态编译小工具

    Java 动态编译小工具是一种实用的程序开发辅助工具,尤其在面对复杂或需要频繁迭代的项目时,它的价值尤为突出。这个工具的核心功能是能够在运行时动态编译Java源代码并将其加载到Java虚拟机(JVM)中,从而实现对...

    java 动态编译特性的展示工程勘误篇

    Java动态编译特性是Java平台一个非常强大的功能,它允许我们在程序运行时将源代码编译成字节码,然后直接加载到JVM中执行。这个特性极大地提升了Java的灵活性和适应性,使得我们可以实现一些在编译时无法确定的复杂...

    java 动态编译.java文件,动态运行类 _1.3

    在Java编程中,动态编译和运行类是一项重要的技术,特别是在需要实时更新代码或实现热部署的场景下。本文将详细讲解如何在Java中实现动态编译.java源代码文件并执行编译后的类。 首先,我们需要理解Java的编译过程...

    java 动态编译.java文件,动态运行类 _1.2

    1. **Java编译API:Javacompiler接口** Java提供了一个内置的`javax.tools.JavaCompiler`接口,它是Java工具接口(Java Tool API)的一部分,允许我们在程序中调用Javac编译器。要使用这个接口,首先需要引入`tools...

    Java类动态加载(一)——java源文件动态编译为class文件

    这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...

    JDK8 下 SpringBoot 应用动态编译 Java 源码并注入 Spring 容器

    SpringBoot 应用动态编译 Java 源码并注入 Spring 容器,实现动态修改接口和抽象类的实现。注意,项目以 Jar 包形式启动时要在命令行引入 tools.jar 的包,IDEA下可直接调试。 基于接口、抽象类实现不停机动态调整...

    利用Java的动态编译、动态加载结合EasyRules实现业务规则的动态性的项目源码

    利用Java的动态编译、动态加载结合EasyRules实现业务规则的动态性的项目源码,具体详情请查看相关博客https://blog.csdn.net/qq_31142553/article/details/85013989

    利用Java动态编译计算数学表达式

    后来考虑到这样编程的任务很重,时间有限 后来在网上搜搜,看到使用动态编译并使用反射机制 ,这样计算表达式的编程就容易多了. 前几天要做一个计算数学表达式的题目,本来计划使用解析表达式的方法来解析各种数学...

    java 动态编译.java文件,动态运行类 _1.1

    在Java编程环境中,有时我们需要在程序运行时动态地编译.java源代码文件并执行新编译的类。这种能力在诸如代码热更新、插件系统或者测试自动化等场景下非常有用。本文将深入探讨如何在Java中实现动态编译与运行。 ...

    JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具

    JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA...

Global site tag (gtag.js) - Google Analytics