JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
是我使用的(和预期的)编译器是空的.
现在,我知道我必须使用JDK,而不是使用JRE作为“运行时”,但是这里是我不明白的:只是把tools.jar放在应用程序的类路径中,那么可以访问Java Compiler API吗?如果这是真的,独立的Java应用程序和基于Web的应用程序之间是否存在(我认为有)差异.
实际上,我试图从PlayFramework webapp传出JavaCompiler,所以我想出来,也许这个解决方案(包括tools.jar)只适用于独立应用程序?
我也尝试创建一个自定义的ClassLoader并且使用反射来调用上面提到的方法,但是我所获得的所有编译器对象都是空的:
ClassLoader classloader = app.classloader(); File file = new File("lib/tools.jar"); URL url = file.toURI().toURL(); URL[] urls = new URL[]{url}; ClassLoader newCL = new URLClassLoader(urls,classloader) { }; Class<?> loadClass = newCL.loadClass("javax.tools.ToolProvider"); Method method = loadClass.getMethod("getSystemJavaCompiler",null); Object object = method.invoke(null); System.out.println("Object: " + object); // NULL
上面的代码说明:
>为了简单起见,我没有包括try / catch.
> app.classloader()是一种播放方法,它返回App的ClassLoader
> tools.jar包含在我的Play项目的lib文件夹中(这意味着它在项目的类路径上 – 根据Play文档)
我确定还有其他一些我需要做的事情之前,Play可以加载Java编译器类,我只是不知道我缺少什么.
像Runtime.exec(“javac myFile.java”)和Eclipse JDT编译器这样的选项对我来说是已知的,但这不是我正在寻找的.
哦,像System.setProperty(“java.home”,“PATH_TO_YOUR_JDK”)这样的东西;然后ToolProvider.getSystemJavaCompiler();正在工作,但我发现这个解决方案如此丑陋.
最好的祝福
编辑:(提供更多信息并反映最后的状态)
这是Web应用程序结构的基本表示形式:
myApp |-conf\... |-lib\MyJar.jar |-lib\tools.jar |-logs\... |-...
MyJar.jar现在有一个Meta-INF / MANIFEST.MF文件,内容如下:
Manifest-Version: 1.0 Sealed: true Main-Class: here.comes.my.main.class Class-Path: tools.jar
没有启动Play应用程序,我正在尝试(在lib文件夹中):java -jar MyJar.jar – 我的简单主方法尝试调用编译器(ToolProvider.getSystemJavaCompiler();)并返回null.所以这让我相信,这个问题与播放无关 – 我甚至不能得到一个编译器,当正常运行我的Jar!