`
onedear
  • 浏览: 69161 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java动态编译(eval)

阅读更多

    因为一些蛋疼的需求,需要其他开发商将相应java代码来实现效果,这里就需要用到动态编译。

    这里网上查了一下资料,忘记来源,自己整理并优化了一番,实现了js的eval效果

/**
 * @author onedear
 *
 */
public class Compiler {
	private static boolean hasFirstInit = false;
	public static String getClassCode (String initParam) {
		StringBuffer sb = new StringBuffer();
		sb.append("public class ETEvaler {")
			.append("public Object eval() {")
			.append(initParam)
			.append("}")
			.append("}");
		return sb.toString() ; 
	}
	
	
	
	public static Object eval(String sourceCode) 
			throws SecurityException, NoSuchMethodException, IOException, 
			ClassNotFoundException, IllegalArgumentException, 
			IllegalAccessException, InvocationTargetException, InstantiationException {
		URLClassLoader classLoader = new URLClassLoader(
				new URL[] { new File(System.getProperty("java.io.tmpdir")).toURI().toURL() });
		Class clazz = null ; 
		boolean hasInit = true ; 
		 try{ 
			 clazz = classLoader.loadClass("ETEvaler");
		 } catch (ClassNotFoundException e) {
			 //说明类未初始化过,需要初始化
			 hasInit = false ; 
		 }
		 if(!hasInit || !hasFirstInit) {
			 hasFirstInit = true;
			 String classCode = getClassCode(sourceCode);
			JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
	        if(compiler == null)
	        	throw new IllegalArgumentException("系统java编译器无法找到,请确认类路径中已经包含tools.jar(注:JDK 6中默认自带,JRE 6中默认不带)");
	        DiagnosticCollector diagnostics = new DiagnosticCollector();
	        StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
	        String fileName = "ETEvaler.java";
	        File file = new File(System.getProperty("java.io.tmpdir"), fileName);
	        PrintWriter pw = new PrintWriter(file);
	        pw.println(classCode);
	        pw.close();
	        Iterable compilationUnits = fileManager.getJavaFileObjectsFromStrings(Arrays.asList(file
	                        .getAbsolutePath()));
	        JavaCompiler.CompilationTask task = compiler.getTask(null,
	                fileManager, diagnostics, null, null, compilationUnits);
	        boolean success = task.call();
	        fileManager.close();
		 }
		//必须重新加载,否则当重新eval时无法立刻生效
		classLoader = new URLClassLoader(
					new URL[] { new File(System.getProperty("java.io.tmpdir")).toURI().toURL() });
        clazz = classLoader.loadClass("ETEvaler");
        Method method = clazz.getDeclaredMethod("eval");
        Object value = method.invoke(clazz.newInstance() );
        return value ; 
		
	}
	
	
}

 调用方式相当简单,如

 

Compiler.eval("System.out.println(\"e1111112222222\");");

String returnValue = Compiler.eval("System.out.println(\"e1111112222222\");return \"returnValue\";");
 

 

 

1
3
分享到:
评论
1 楼 li7jia7 2011-08-27  
package com.test;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import com.sun.tools.javac.Main;

public class Compiler {

private static boolean hasFirstInit = false;

public static String getClassCode(String initParam) {
StringBuffer sb = new StringBuffer();
sb.append("public class ETEvaler {").append("public void eval() {").append(initParam).append("}").append("}");
return sb.toString();
}

public static Object eval(String sourceCode) throws SecurityException, NoSuchMethodException, IOException,
ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException,
InstantiationException {
URLClassLoader classLoader = new URLClassLoader(new URL[] { new File("c://").toURI().toURL() });
Class clazz = null;
boolean hasInit = true;
try {
clazz = classLoader.loadClass("ETEvaler");
} catch (ClassNotFoundException e) {
// 说明类未初始化过,需要初始化
hasInit = false;
}
if (!hasInit || !hasFirstInit) {
hasFirstInit = true;
String classCode = getClassCode(sourceCode);
String fileName = "ETEvaler.java";
File file = new File("c://", fileName);
PrintWriter pw = new PrintWriter(file);
pw.println(classCode);
pw.close();
Main.compile(new String[] { "-classpath", "", "c://ETEvaler.java" });

}
// 必须重新加载,否则当重新eval时无法立刻生效
classLoader = new URLClassLoader(new URL[] { new File("c://").toURI().toURL() });
clazz = classLoader.loadClass("ETEvaler");
Method method = clazz.getDeclaredMethod("eval");
Object value = method.invoke(clazz.newInstance());
return value;
}

public static void main(String[] args) {
try {
Compiler.eval("System.out.println(\"e1111112222222\");");
} catch (Exception e) {
e.printStackTrace();
}
}
}

相关推荐

    在java中利用动态编译实现eval

    在Java中,实现类似`eval`功能的一种方法是利用Java的动态编译API,例如`javax.tools.JavaCompiler`接口和相关的工具类。以下是一个简单的示例,演示如何将字符串转换为Java方法并执行: ```java import javax....

    java动态特性eval

    Java动态特性eval的相关实现主要涉及Java的反射机制、表达式求值以及编译器接口。在JavaScript中,`eval()`函数能够将一个字符串作为代码执行,从而实现动态编程。Java中虽然没有直接对应的内置方法,但通过一些技术...

    java实现js中eval功能

    在Java中,这可以通过编译和执行Java的`ScriptEngine`来实现,特别是`JavaScript`引擎,如`Nashorn`(在Java 8中)或`Rhino`(在更早的版本中)。以下是一个使用`Nashorn`引擎的例子: ```java import javax.script...

    java实现eval函数

    `eval`函数在Java中并不是标准库的一部分,因为出于安全考虑,Java的设计者们避免了动态执行代码的能力。但是,如果你需要在Java中实现类似的功能,可以创建一个自定义的解析器或利用一些第三方库来解析和执行给定的...

    java解析公式 eval.jar

    6. **性能优化**:由于动态解析和执行公式可能带来性能开销,`eval.jar`可能采用了编译优化技术,将公式编译为更高效的形式,以提高计算速度。 7. **API使用**:理解库的API是关键。通常,会有如`Evaluator`这样的...

    编译原理实验(基于表达式的计算器ExprEval)

    这个实验“基于表达式的计算器ExprEval”旨在让学生深入理解编译器的工作原理,并通过实际操作来掌握编译技术。下面将详细介绍这个实验涉及的知识点,以及如何进行实践。 1. **词法分析(Lexical Analysis)**: ...

    java动态代码执行

    Java动态代码执行是一种在运行时编译和执行代码的技术,它可以极大地提高程序的灵活性和可扩展性。在Java中,Groovy是一个强大的脚本语言,它与Java语法兼容,并且可以无缝集成到Java应用程序中,使得动态代码执行变...

    Java反编译工具和关系型数据库建模工具

    对于Java开发者来说,了解和使用Java反编译工具以及关系型数据库建模工具是提升效率和优化项目的关键。下面将详细介绍这两个主题。 首先,Java反编译工具是程序员在面对已编译的.class文件,无法直接查看源代码时的...

    在程序中实现对java源文件编译的3种方法文.pdf

    本方法适用于在Java程序内部动态编译源代码的情形,例如需要通过放置一些源代码来实现程序功能的动态扩展。此方法通过调用`Runtime`类或`ProcessBuilder`类来执行`javac`命令。 **准备工作**: 1. **源文件路径**...

    JavaREPL是一个Java语言读入-求值-打印-循环(Read-Eval-Print-Loop)功能实现

    JavaREPL,全称为Java Read-Eval-Print Loop,是Java开发者的一种实用工具,它允许程序员在交互式环境中测试代码片段、快速实验新概念或调试程序。REPL是许多编程语言的标准特性,如Python和Lisp,而在Java世界中,...

    JavaRunWeb:基于springboot + maven的可在线动态解析编译Java代码的学习系统,作为学生可以进行编程练习,考试作答,课件观看和视频学习的功能,老师可对学习资源进行管理,也可查看学生做题情况分和可题的做题对错记录,并且将学生分数和每道题的对错情况以图表的形式呈现给老师

    在JavaRunWeb系统中,动态解析和编译Java代码的能力是其核心特性之一。这通常涉及到Java的JShell(也称为REPL,Read-Eval-Print Loop)或者自定义的Java编译器接口。这样的功能允许学生实时测试代码,获取即时反馈,...

    Java反编译工具

    计算机软件反向工程(Reverse engineering)也称为计算机软件还原工程,是指通过对他人软件的目标程序(可执行程序)进行“逆向分析、研究”工作,...反编译作为自己开发软件时的参考,或者直接用于自己的软件产品中。

    Java数学表达式计算(Expression Evaluator)

    在Java编程中,处理数学表达式的计算是一项常见的任务,尤其在需要动态计算或者解析用户输入时。本主题将深入探讨如何在Java中实现一个数学表达式计算器,这通常被称为"Expression Evaluator"。我们将讨论相关的技术...

    Z.Expressions.Eval.2.4.2

    Z.Expressions.Eval 2.4.2 是一个专注于表达式解析的开源库,它由Java语言构建,设计为超轻量级且高度可扩展。这个工具包的主要目标是提供一个强大的框架,允许开发者在应用程序中方便地处理和执行自定义的公式化...

    CodeEval:Java中一些代码eval问题的一些解决方案

    在Java中,如果你需要动态执行代码,你可能需要借助于Java的反射API或者使用Java Compiler API来编译和运行Java源代码。下面是一些处理代码评估问题的常见方法: 1. **Java反射API**: 反射API允许在运行时检查类...

    Java类似JavaScript的eval实现,和随机4个数计算24点

    在Java中,没有内置的`eval`函数,像JavaScript那样可以直接执行字符串形式的代码。但是,我们可以模拟实现一个类似的函数,来解析并计算简单的数学表达式。以下是一个基于给定内容的简化的Java `Eval` 类实现: ``...

    05-python-修饰符的使用-operator模块-作用域-动态编译

    `exec`和`eval`函数则可以执行已编译的代码或表达式,这在动态生成代码和运行时计算方面非常实用,但也要注意安全风险,因为它们能执行任意的Python代码。 通过学习这些知识点,你可以更好地理解和利用Python的特性...

    Java中动态规则的实现方式示例详解

    Java中的动态规则实现是软件开发中应对业务规则频繁变动的一种策略。这些规则可能涉及复杂的业务逻辑,需要在运行时能够灵活调整,而不必修改源代码并重新编译。本篇文章将详细探讨Java中三种常见的动态规则实现方式...

    ide-eval-resetter

    在Java平台上,jar文件是一种用于打包和分发类库或应用程序的标准格式,它包含了一系列编译后的Java类和其他资源。要使用这个插件,用户需要将这个jar文件导入到IntelliJ IDEA的插件系统中。 安装和使用ide-eval-...

Global site tag (gtag.js) - Google Analytics