您的位置:首页 > 编程语言 > Java开发

ToolProvider.getSystemJavaCompiler() Return NULL!【转】

2013-02-23 19:45 435 查看
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已经编译成功了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: