返回null的Java编译器

返回null的Java编译器,java,compiler-construction,Java,Compiler Construction,我正在创建一个类似Codingbat.com的程序 在运行时,它需要编译代码,然后执行它。这一切都已得到处理。 目前,我不得不使用JavacTool,这需要将它打包在一起 我有两个基本问题: 1) 如何阻止ToolProvider.getSystemJavaCompiler()在从可执行jar运行时返回null 2) 如果上面不可能,是否有方法添加com.sun.tools.javac.api.JavacTool的jar;没有将其作为引用库,从而使其像常规导入一样工作 感谢您回答这个问题,如果您

我正在创建一个类似Codingbat.com的程序

在运行时,它需要编译代码,然后执行它。这一切都已得到处理。 目前,我不得不使用JavacTool,这需要将它打包在一起

我有两个基本问题:

1) 如何阻止ToolProvider.getSystemJavaCompiler()在从可执行jar运行时返回null

2) 如果上面不可能,是否有方法添加com.sun.tools.javac.api.JavacTool的jar;没有将其作为引用库,从而使其像常规导入一样工作

感谢您回答这个问题,如果您愿意,我可以上传带有引用库的Jar,而不带引用库的Jar

需要明确的是,带有引用库的jar是可行的,但它比通过eclipse运行的jar要大得多,而且慢得多,后者使用的是JavaCompiler,而不是JavacTool

谢谢

编辑:

我很确定这在java中是可能的,就像我以前看到的那样,但是忘记了在哪里以及如何运行。

我怀疑这只是运行哪个版本的java的问题。如果您运行JRE附带的版本,它将没有可用的工具。如果您运行JDK附带的版本,它会

例如,这里有一个简短但完整的程序:

import javax.tools.*;

public class Test
{
    public static void main(String[] args)
    {
        System.out.println(ToolProvider.getSystemJavaCompiler());
    }
}
在我的笔记本电脑上使用JRE版本的java.exe运行它:

c:\Users\Jon\Test>"\Program Files\java\jre7"\bin\java Test
null
现在使用JDK:

c:\Users\Jon\Test>"\Program Files\Java\jdk1.7.0"\bin\java Test
com.sun.tools.javac.api.JavacTool@441944ae

因此,请尝试显式地指定与JDK关联的Java二进制文件。

这样您就知道所有用户都将安装JDK,并且您知道在Java程序中如何查找JDK的类路径。您不需要加载DLL。您需要在tools.jar中加载com.sun.tools.javac.api.JavacTool类。请参阅如何加载tools.jar

因此我有一个问题,如果我要创建一个jar,并使用Runtime.exec函数来执行这样的任务,那么这个功能是否会像您发布的CMD一样工作?@Legend:老实说,我不知道。如果它能找到正确的二进制,那么可能。。。但这将是一个有点笨拙的引导程序。啊,我明白了,有没有办法让它以文件(.jar,.exe)的形式执行,并让它在编译器中这样做,我宁愿不使用.batthough@Legend:您有没有理由不将.jar关联更改为使用JDK而不是JRE?或者这将被分发给其他人,而你不想解释这一点?如果是这样的话,您可能会想添加一个jar文件作为依赖项—它不确定“不将其作为引用库”是什么意思。好吧,它应该只有33kb左右,有了引用库它是6.2mb。另外,JavaCompiler在Eclipse中运行良好,我可以指定在Eclipse中使用JDK运行。如果这在java中是可能的,那么回答第一个问题就太完美了。所有用户都将拥有JDK。另外,如果我能找到一种方法来获取JDK目录的文件表示形式,我怎么能用它来做我想做的事情呢?我知道tools.jar,这是最新的。这就是为什么它是6mb,而不是33kb。@Legend Uhmm。。。为了在搜索JDK目录后动态加载.jar文件…我不知道。试着拨弄System.load和System.LoadLibrary好吧,我把属性弄得一团糟。System.getProperty(“java.library.path”).split(;”[0]返回JDK的位置。你知道我需要加载什么DLL来指定JDK而不是JRE吗?啊,所以一旦我有了这个类,我就使用反射来获取返回编译器的方法?如果我错了,请纠正我。