我知道这已经被问及了很多,但我仍然没有一个很好的解决方案,我仍然不明白一些部分.所以我需要以编程方式编译* .
java文件.
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!