在代码中编译,没有得到我想要的行为. [英] Compiling within code, not getting behavior I'd like.
本文介绍了在代码中编译,没有得到我想要的行为.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
所以我有一些代码-我想编译字符串'temp',然后执行它,然后更改字符串,重新编译并执行.问题是当前它只是首先执行第一部分代码.
So I've got some code - I'd like to compile the string 'temp' then execute it, then change the string, recompile and execute. Problem is that currently it's just executing the first bit of code first.
我希望:
This is in another java file
How about now?
我得到:
This is in another java file
This is in another java file
完整代码如下,任何帮助表示赞赏.
Full code follows, any help appreciated.
import java.io.IOException;
import java.util.Arrays;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
public class Another2 {
public static void main(String args[]) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
//First run
String temp = "public class HelloWorld {\n" + " public static void main(String args[]) {\n"
+ " System.out.println(\"First Compiled Class\");\n" + " }\n" + "}";
JavaFileObject file = new JavaSourceFromString("HelloWorld", temp);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
task.call();
try {
Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class })
.invoke(null, new Object[] { null });
} catch (Exception e) {
// handled it
}
//second run
temp = "public class HelloWorld {\n" + " public static void main(String args[]) {\n"
+ " System.out.println(\"How About Now?\");\n" + " }\n" + "}";
file = new JavaSourceFromString("HelloWorld", temp);
Iterable<? extends JavaFileObject> compilationUnits2 = Arrays.asList(file);
task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits2);
task.call();
try {
Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class })
.invoke(null, new Object[] { null });
} catch (Exception e) {
// handled it
}
}
}
推荐答案
事实证明,我正在寻找的代码是:
It turns out that the code I was looking for was:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
public class AnotherClassLoaderRunner {
private static final String nameOfDemoClass = "ByeWorld";
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
// Start compilation and loading of first class.
String sourceCode = "public class " + nameOfDemoClass + " {\n" + " public static void main(String args[]) {\n"
+ " System.out.println(\"First of our Compiled Class\");\n" + " }\n" + "}";
AnotherClassLoader classLoader = new AnotherClassLoader(AnotherClassLoaderRunner.class.getClassLoader(), nameOfDemoClass);
Class<?> myclass = classLoader.loadClass(nameOfDemoClass,sourceCode);
Method mymethod = myclass.getDeclaredMethod("main", new Class[] { String[].class });
mymethod.invoke(null, new Object[] { null });
// Start compilation and loading of second class.
sourceCode = sourceCode.replace("First of our Compiled Cla", "Second of our Compiled Cla");
classLoader = new AnotherClassLoader(AnotherClassLoaderRunner.class.getClassLoader(), nameOfDemoClass);
myclass = classLoader.loadClass(nameOfDemoClass,sourceCode);
mymethod = myclass.getDeclaredMethod("main", new Class[] { String[].class });
mymethod.invoke(null, new Object[] { null });
}
}
class AnotherClassLoader extends ClassLoader {
private static final String pathToClassDirectory = "file:/Users/*********/Documents/workspace/Dynamic/src/";
private String targetName;
public AnotherClassLoader(ClassLoader parent, String target) {
super(parent);
targetName = target;
}
public Class<?> loadClass(String name, String compileme) throws ClassNotFoundException {
if (!targetName.equals(name)) {
return super.loadClass(name);
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileObject file = new JavaSourceFromString(name, compileme);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, new DiagnosticCollector<JavaFileObject>(), null, null,
compilationUnits);
task.call();
// THE CLASSFILE FOR THE SYSTEM EXSITS AT THIS POINT, thought how it
// chooses the directory escapes me.
try {
String url = pathToClassDirectory + targetName + ".class";
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
InputStream input = connection.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int data = input.read();
while (data != -1) {
buffer.write(data);
data = input.read();
}
input.close();
byte[] classData = buffer.toByteArray();
return defineClass(targetName, classData, 0, classData.length);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
这篇关于在代码中编译,没有得到我想要的行为.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文