以编程方式编译java文件

前端之家收集整理的这篇文章主要介绍了以编程方式编译java文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我知道这已经被问及了很多,但我仍然没有一个很好的解决方案,我仍然不明白一些部​​分.所以我需要以编程方式编译* . 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!

解决方法

Web应用程序和独立应用程序之间没有区别.

您不应该将tools.jar打包到您的webapp类路径中. Java中的类加载器通常只能从底部起作用.因此,作为jdk一部分的ToolProvider将不会在webapp类路径中看到您的tools.jar(它不能向下看到webapp类路径).

解决方案:使用JDK,确保指向或将tools.jar放在Java ext dir中.您可以通过将属性-Djava.ext.dir设置为您喜欢的任何目录来覆盖ext dir.

猜你在找的Java相关文章