最近接到一个很特殊的case,用户要求自己在客户端以java Code的形式输入一些业务逻辑;我第一反应就是,用户他会写java Code吗?哎,不过面对用户的需求,我们编码人员有啥资格说不。
实现思路:
1.得到用户输入的java code片段
2.把java code片段包装成一个类
3.建临时java文件
4.动态编译该文件
5.得到class文件然后动态调用
6.虚拟机退出时删除临时的java文件和编译产生的class文件
20110602 14:13 今天发现了新的解决方案,就是使用beanshell,现在正在学习,等解决了问题再分享。嘿嘿
下面的程序源代码实现了用户输入一段java Code,然后动态编译,最后动态调用。希望对有相同需要的人有帮助。嘿嘿
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Random;
import com.sun.tools.javac.*;
public class RuntimeCode {
private static Main javac = new Main();
public static void main(String[] args) throws Exception{
while(true){
BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Please enter your java code: ");
String code = sysin.readLine();
File returnFile = compile(code);
if(returnFile != null){
run(returnFile);
}else{
System.out.print("error hanppen");
}
}
}
/**
* call this method to create a temp .java file and compile it.
* @param code
* @return
* @throws IOException
* @throws Exception
*/
private synchronized static File compile(String code) throws IOException,Exception{
File file;
file = File.createTempFile("JavaRuntime", ".java",
new File(System.getProperty("user.dir")));
file.deleteOnExit();
String filename = file.getName();
String classname = getClassName(filename);
PrintWriter out = new PrintWriter(new FileOutputStream(file));
out.println("public class " + classname + "{");
out.println("public static void main(String[] args) throws Exception{");
out.println(code);
out.println("}");
out.println("}");
out.flush();
out.close();
String[] args = new String[]{"-d", System.getProperty("user.dir")+"\\bin",filename};
int status = javac.compile(args);
switch(status){
case 0 :
//exit_ok
return file;
case 1 :
//exit_error
return null;
case 2 :
//exit_cmderr
return null;
case 3 :
//exit_syserr
return null;
case 4 :
//exit_abnormal
return null;
}
return file;
}
/**
* call this method to run the compiled .class file.
* @param file
*/
private static synchronized void run(File file){
String filename = file.getName();
String classname = getClassName(filename);
File classFile = new File(file.getParent()+"\\bin", classname + ".class");
classFile.deleteOnExit();
try{
Class cls = Class.forName(classname);
Method main = cls.getMethod("main", new Class[]{String[].class});
main.invoke(null, new Object[]{new String[0]});
}catch(SecurityException se){
se.printStackTrace();
}catch(NoSuchMethodException nme){
debug("a matching method is not found or if then name is or:" + nme.toString());
}catch(InvocationTargetException ite){
debug("Exception in main:" + ite.getTargetException());
}catch(Exception e){
debug(e.toString());
}
}
/**
* print error message.
* @param msg
*/
private static void debug(String msg){
System.err.println(msg);
}
/**
* call this method to get a class name by input .java file name.
* @param filename
* @return
*/
private static String getClassName(String filename){
return filename.substring(0, filename.length()-5);
}
}
分享到:
相关推荐
在Java编程中,有时我们需要在运行时动态地编译源代码文件,并将其打包成可执行的JAR(Java Archive)文件。这样的需求通常出现在我们希望根据用户输入或特定条件生成并执行新的代码逻辑时。本教程将深入讲解如何...
Java 动态编译源码并调用是Java开发中的一种高级技巧,它允许程序在运行时根据需要编译和执行新的代码。这种能力在某些场景下非常有用,例如插件系统、元编程或者在运行时自动生成和执行特定逻辑。下面我们将详细...
Java动态编译指的是在程序运行时将Java源代码编译为字节码并加载到Java虚拟机(JVM)中的过程。这种技术在许多场景下非常有用,例如在开发环境中进行快速迭代、AOP(面向切面编程)或运行时代码生成等。Java的`javax...
在Java编程中,动态编译和运行类是一项重要的能力,特别是在需要实时更新代码或实现热部署的场景下。本文将深入探讨如何利用Java的API来动态编译.java源文件,并执行编译后的类。 首先,Java的`javac`命令行工具是...
这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...
在Java编程中,动态编译和运行类是一项重要的技术,特别是在需要实时更新代码或实现热部署的场景下。本文将详细讲解如何在Java中实现动态编译.java源代码文件并执行编译后的类。 首先,我们需要理解Java的编译过程...
1. **Java编译API:Javacompiler接口** Java提供了一个内置的`javax.tools.JavaCompiler`接口,它是Java工具接口(Java Tool API)的一部分,允许我们在程序中调用Javac编译器。要使用这个接口,首先需要引入`tools...
Java内存动态编译执行是Java程序运行时的一个关键特性,它涉及到JVM(Java虚拟机)的即时编译器(JIT,Just-In-Time Compiler)和元空间(Metaspace)等核心概念。在Java的世界里,代码首先会被解释器逐行解释执行,...
Java动态编译是一种技术,允许程序在运行时将源代码转换为字节码并加载到JVM(Java虚拟机)中。这种能力使得Java应用程序能够根据需要编译和执行新的代码,增强了软件的灵活性和可扩展性。在给定的场景中,用户通过...
使用`Class.forName()`加载类后,可以调用`newInstance()`方法创建类的实例,然后调用其方法执行动态编译的代码。 以上步骤概括了动态编译字符串成Java并加载到JVM的过程。这个技术虽然强大,但也需要注意安全问题...
内存中动态编译执行Java代码是一种高级编程技巧,它允许我们在程序运行时根据需要创建、编译和执行新的Java代码。这种技术在某些场景下非常有用,比如在元编程、插件系统、自定义脚本执行或者代码热更新中。在Java中...
Java调用动态链接库(DLL)是Java编程中一个比较特殊的技术,主要涉及到Java与本地代码的交互。在Windows系统中,DLL(Dynamic Link Library)是实现函数复用的一种方式,它包含了一系列可供其他程序调用的函数或数据...
使用JNI,你需要编写一个Java类,声明native方法,然后使用`javah`工具生成C/C++头文件,再编写对应的C/C++代码实现这些方法,最后编译成动态库供Java调用。 以下是一个简单的JNI示例,同样调用`doSomething()`函数...
Jdk 动态编译 Java 源码测试 Demo 通过 Jdk 工具类,直接将 Java 源码编译为 Class 字节码,并可加载为 Class 对象; 实例化后,可调用实例对象的方法 通过上面的实现,可以在线动态修改源码,并触发编译,加载到...
在本文中,我们将深入探讨Lua的编译与反编译过程,以及涉及到的相关工具和Java源码。 首先,我们需要理解Lua的编译过程。Lua代码通常是文本形式的,它被编译成中间表示(Lua虚拟机字节码,即LCB),这个过程被称为...
下面我们将详细讨论如何在Java中调用动态链接库,并以Linux环境下的SO库为例,提供一个实例。 1. **Java Native Interface (JNI)**: JNI是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI...
Java反编译是将已编译的Java字节码转换回源代码的过程,这对于理解类库的工作原理、学习代码实现或者在没有源代码的情况下调试二进制程序非常有用。JD-GUI是一款流行的Java反编译工具,尤其适用于Mac用户。在本文中...
你可以通过下载源代码,然后在命令行调用相应的编译脚本来使用FernFlower。 对于更高级的场景,例如批量反编译或者集成到构建过程中,Procyon和 Krakatau 提供了更多的选项。Procyon是一个强大的Java编译器和反...