`
onedear
  • 浏览: 67997 次
  • 性别: 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

    我们知道,在很多脚本语言中都有eval函数,它可以把字符串转换为表达式并执行.如在javaScript中: var str = aid.value + ".style.top = 10;"  把一个id为"aid"的控制的值取...这样的功能对于动态构造变量是有非常重要

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

    相对新手而言,这个实验有较大难度。这里提供大家一个参考。但希望大家还是自己写,你会发现原来这么回事。不要把问题想得太复杂了。

    Groovy大量计算导致oom的解决办法

    问题原因分析:使用ScriptEngine.eval每次都会对脚本进行编译,生成一个新的类,被GroovyClassLoader加载,大量执行计算后,将导致被加载的类数量不断增加,最终OOM。 解决办法:对计算的表达式expression进行预...

    基于表达式的计算器ExprEval

    实现了四则运算+,-,*,/,max,min,sin,cos四个内值函数。 还有求负和求幂运算。 实现了三元运算符?: 实现了逻辑运算& ! ! 实现了比较运算符 > < >= 可以单独求布尔表达式的值。...编译原理作业

    javascript中eval函数用法分析

    本文实例分析了javascript中eval函数用法。分享给大家供大家参考。具体分析如下: eval()只有一个参数,如果传入的参数不是字符串,则直接返回这个参数。否则会将字符串当成js代码进行编译,如果编译失败则...

    xml执行java源码-spring-boot-docker:《动手玩Docker》示例代码:Docker+SpringBoot:快速搭建和部

    eval $(docker-machine env) 1、Maven编译工程 下载源码到本地,进入工程目录,执行maven编译 git clone https://github.com/bingoHuang/spring-boot-docker.git cd spring-boot-docker tree 项目结构: ├── ...

    JSP-Webshells:收集各种实现方法的JSP Webshel​​l。收集JSP Webshel​​l的各种姿势

    Webshel​​ls集合BCEL字节码的JSP Webshel​​l自定义类加载器的JSP Webshel​​l ScriptEngine.eval的JSP Webshel​​l URLClassLoader加载远程jar的JSP Webshel​​l javac动态编译类的JSP Webshel​​l jdk....

    yado-js:另一个Java注释符号

    这需要预编译您的代码或使用eval动态评估您的“及时”已终止代码(调试是什么?IDE?)。 通过数据结构进行仿真:此库的情况。 我们使用原始的javascript数据结构,该数据结构将被解释为Do表示法。 这带来了: :...

    java8看不到源码-gueb:格布

    java8 看不到源码GUEB静态分析器检测二进制上的 Use-After-Free 推介会 GUEB 是一个静态分析器,对二进制文件执行释放后使用检测。 该工具仍在开发中,欢迎任何评论/帮助。 总之,GUEB 对二进制代码执行值分析,它...

    aiprojekt:课程中的项目[DD2380]人工智能

    指示 为了能够编译和运行: ...可以生成三种类型的结果:“ make eval-nogrammar”“ make eval-grammar”“ make eval-userlearning”这大约需要20分钟才能完成,输出在res / evaluation文件夹中,每种

    pyterrier:建立在http之上的用于执行信息检索实验的Python框架

    如果您可以自己编译和安装pytrec_eval,它应该可以正常工作。索引编制PyTerrier具有许多用于创建索引的有用的类: 您可以使用TRECCollectionIndexer从TREC格式的集合中创建索引。 对于TXT,PDF,Microsoft Word文件...

    python慕课笔记 Python语言程序设计 嵩天笔记整理

    静态语言:编译执行:C/C++\Java,执行速度快 脚本语言;解释执行:Python、JavaScript、PHP,维护灵活程序的基本编写方法:IPO Input输入、Process处理、Output输出 1.3温度转化实例 #TempConvert.py TempStr = ...

    iter.js:类似于C#LINQJavaScript迭代器库

    iter.js-将迭代器添加到JavaScript 该库允许您使用类似于C#LINQ或Java 8流的语法编写数据处理语句,例如: var firstTenPrimes = iter .... 这里的'$ % 2 === 0'是一个快速表达式(使用eval编译quic

    JS代码混淆初步

    还有些加密的手段,通过复杂的变换,改变源码,但最终都逃不脱最后的审判,像unescape,[removed],eval语句来还原。对于JS代码的保护,最好的手段就是混淆,混淆的目的就是让读懂代码的成本比直接写代码的成本高,...

    用Python编写一个简单的Lisp解释器的教程

    几年前,我介绍过如何使用Java编写一个Scheme解释器,同时我还使用Common Lisp语言编写过一个版本。这一次,我的目的是尽可能简单明了地演示一下Alan Kay所说的“软件的麦克斯韦方程组” (Maxwell’s Equations of ...

    编写一个javascript元循环求值器的方法

    在上一篇文章中,我们通过AST完成了微信小程序组件的多端编译,在这篇文章中,让我们更深入一点,通过AST完成一个javascript元循环求值器 结构 一个元循环求值器,完整的应该包含以下内容: tokenizer:对代码文本...

    calculator:安卓简单计算器

    信息:如源代码的 url、创建者的电子邮件和 apk 的编译日期 退出:退出 其他 科学记数法支持 支持/问题 如果您遇到任何问题,请首先确保您使用的是此代码的最新版本,并且您已将软件包更新为最新的可用版本(请参阅...

    rdffederator:从 code.google.comprdffederator 自动导出

    关于 SPLENDID 为分布式、链接的 RDF 数据源提供联合基础结构。 SPARQL 查询在一组预先配置的 SPARQL 端点上透明地执行。 自动源选择和查询优化..../SPLENDID.sh SPLENDID-config.n3 eval/queries/cd/ 自定义 SPLENDI

    Tcl_TK编程权威指南pdf

    使用cgi创建动态页面 guestbook.cgi脚本程序 定义表单以及处理表单数据 cgi.tcl软件包 接下去的几步 第4章 tcl中的字符串处理 string命令 append命令 format命令 scan命令 binary命令 相关章节 第5章...

    Python核心编程第二版(ok)

     1.3.12 解释性和(字节)编译性   1.4 下载和安装Python   1.5 运行Python   1.5.1 命令行上的交互式解释器   1.5.2 从命令行启动脚本   1.5.3 集成开发环境   1.5.4 其他的集成开发环境和执行...

Global site tag (gtag.js) - Google Analytics