`
hunaifei2008
  • 浏览: 27819 次
  • 性别: Icon_minigender_1
  • 来自: 烟台
社区版块
存档分类
最新评论

ToolProvider.getSystemJavaCompiler() Return NULL!【转】

阅读更多

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

/**
* @author YuFa
*
*/
publicclass CompilerTest { 

publicstaticvoid main(String[] args) throws Exception { 
String source = "public class Main {" +
"public static void main(String[] args) {" +
"System.out.println(\"Hello World!\");" +
"} " +
"}"; 


JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); 
StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main", source); 
List<StringSourceJavaObject> fileObjects = Arrays.asList(sourceObject); 
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects); 

boolean result = task.call(); 
if (result) { 
System.out.println("Compile succeeded!"); 
} else {
System.out.println("Compile failed!"); 
}


staticclass 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; 


@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { 
return content; 


}


注意编译上面代码是需要JRE6的,因为JavaCompiler等类都是在JDK6中提供的。当我运行上面代码的时候,结果却抛出了null pointer exception. 问题出在如下这行代码...

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

ToolProvider.getSystemJavaCompiler()返回的是NULL,因此在调用compiler.getStandardFileManager(null, null, null)的时候抛出了null pointer exception. 

为啥会这样呢?查看了下ToolProvider的源代码,发现如下这么一段....

 

private static final String[] defaultToolsLocation = { "lib", "tools.jar" };privatestatic Class<?> findClass()
throws MalformedURLException, ClassNotFoundException
{
try {
return enableAsserts(Class.forName(defaultJavaCompilerName, false, null));
} catch (ClassNotFoundException e) {
// ignored, try looking else where
}
File file = new File(System.getProperty("java.home"));
if (file.getName().equalsIgnoreCase("jre"))
file = file.getParentFile();
for (String name : defaultToolsLocation)
file = new File(file, name);
URL[] urls = {file.toURI().toURL()};
ClassLoader cl = URLClassLoader.newInstance(urls);
cl.setPackageAssertionStatus("com.sun.tools.javac", true);
return Class.forName(defaultJavaCompilerName, false, cl);
}


我已经设置了JAVA_HOME环境变量,指向了我的JRE安装目录C:\Java\jre6, 注意查找文件的代码...

 

for (String name : defaultToolsLocation)
file = new File(file, name);

 

也就是说会查找目录C:\Java\jre6\lib\tools.jar 

但是注意的是tools.jar并不在jre中,而是在jdk安装目录下,因此我手动把这个jar文件从jdk目录下拷贝到了jre目录下,再次运行上面的代码就没有问题了!同时注意到在代码工程目录下生成了一个名为Main.class的文件,这个确实说明了动态类Main已经编译成功了!

 

分享到:
评论
2 楼 hunaifei2008 2013-07-23  
123taobing 写道
怎么 我改了之后用 eclipse还是出错啊

确认一下你的JRE安装目录是否与JAVA_HOME环境变量一致,然后再确认tools.jar是否存在
1 楼 123taobing 2013-07-17  
怎么 我改了之后用 eclipse还是出错啊

相关推荐

    java深度历险.pdf

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable&lt;? extends JavaFileObject&gt; ...

    Java深度历险

    接着,我们使用`ToolProvider.getSystemJavaCompiler()`方法获取系统默认的Java编译器实例。然后,通过`JavaCompiler`接口提供的方法,我们创建了一个`StandardJavaFileManager`对象,并使用自定义的`...

    Java类动态加载(一)——java源文件动态编译为class文件

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int result = compiler.run(null, null, null, compilationUnits); if (result == 0) { System.out.println("Compilation successful"); } ...

    Java动态编译执行代码示例

    JavaCompiler可以通过ToolProvider.getSystemJavaCompiler()方法获取。如果JDK提供了JavaCompiler,则返回JavaCompiler对象,否则返回null。 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 第二...

    Java语言-动态编译代码并热加载类

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable&lt;? extends JavaFileObject&gt; fileObjects...

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

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable&lt;? extends JavaFileObject&gt; fileObjects...

    java动态编译java源文件

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); // 源文件列表 List&lt;JavaFileObject&gt; sources = ...

    JAVAC动态编译

    要使用`JavaCompiler`,我们需要获取到`ToolProvider`的实例,然后调用其`getSystemJavaCompiler()`方法来获取编译器对象。接着,我们需要创建`StandardJavaFileManager`来管理源文件和编译结果。以下是一个简单的...

    Java6JDK1.6新特性总结大全附代码.docx

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable&lt;? extends JavaFileObject&gt; ...

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

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); JavaFileObject source = new SimpleJavaFileObject(URI.create("string:///" + HelloWorld.class.getCanonicalName().replace('.', '/') + Kind....

    Java实现动态创建类操作示例

    JavaCompiler cmp = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = cmp.getStandardFileManager(null, null, null); JavaFileObject jfo = new StringJavaObject(clsName, sourceStr); List...

    Java运行时动态生成类实现过程详解

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); int compilationResult = compiler.run(null, null, null, '/path/Test.java'); 使用Java Compiler API可以直接在内存中完成编译,输出的class内容...

Global site tag (gtag.js) - Google Analytics