问题描述
今天看到这个http://www.infoq.com/cn/articles/cf-java-byte-code想试一试,但是编译通过之后的,想执行结果那,总是不成功。现在将代码贴上,望大神指点!package com.deep.byteOpera;import java.io.IOException;import java.lang.reflect.Method;import java.net.URI;import java.net.URISyntaxException;import java.util.Arrays;import javax.tools.JavaCompiler;import javax.tools.JavaCompiler.CompilationTask;import javax.tools.JavaFileObject;import javax.tools.SimpleJavaFileObject;import javax.tools.StandardJavaFileManager;import javax.tools.ToolProvider;public class CompilerTest { static class StringSourceJavaObject extends SimpleJavaFileObject { private String content = null; public StringSourceJavaObject(String name, String content) throws URISyntaxException { super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); this.content = content; } public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return content; } } public static void main(String[] args) throws Exception { String className = "MainTest"; String methodName = "main"; String source = "public class "+className+" { public static String "+methodName+" () { System.out.println("Hello World!"); return "haha";} }"; JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //动态编译 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject(className, source); Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject); CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects); boolean result = task.call(); System.out.println(result); if (result) { //编译成功,进行加载执行// ClassLoader loader = fileManager.getClass().getClassLoader();// ClassLoader loader = fileObjects.getClass().getClassLoader();// ClassLoader loader = task.getClass().getClassLoader();// ClassLoader loader = compiler.getClass().getClassLoader(); ClassLoader loader = CompilerTest.class.getClassLoader(); // ClassLoader loader = ToolProvider.getSystemToolClassLoader(); try { Class<?> clazz = loader.loadClass(className); Method method = clazz.getMethod(methodName, new Class<?>[] {}); Object value = method.invoke(null, new Object[] {}); System.out.println(value); } catch (Exception e) { e.printStackTrace(); } } }} 问题补充:系统报的错误是java.lang.ClassNotFoundException: MainTestat java.net.URLClassLoader$1.run(URLClassLoader.java:200)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:188)at java.lang.ClassLoader.loadClass(ClassLoader.java:307)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)at java.lang.ClassLoader.loadClass(ClassLoader.java:252)at com.deep.byteOpera.CompilerTest.main(CompilerTest.java:59)
解决方案
其实编译后会生成一个class文件,关键是文件的路径有问题,所以就找不到了加上编译选项,指定目录Iterable<String> options = Arrays.asList("-d", "bin","-sourcepath", "src");CompilationTask task = compiler.getTask(null, null, diagnostics,options, null, compilationUnits);我项目的源代码文件在“src”目录下,生产的class文件在“bin”目录下,你依据自己情况修改。
解决方案二:
学习了.....
解决方案三:
引用method.invoke(null, new Object[] {}); 你定义的方法没有参数吧method.invoke(null);