【问题标题】:Programmatically compile Java class in a package stored in an arbitrary sub folder以编程方式编译存储在任意子文件夹中的包中的 Java 类
【发布时间】:2010-07-11 09:19:43
【问题描述】:

我希望用 Java 编译一个应用程序,它由一定数量的包中的不同数量的 Java 类组成。在命令行中,我可以切换到包含根包的文件夹并输入:

javac rootpackage/subpackage/*.java

javac rootpackage/*/*.java

编译我的根包的所有主要子包中的所有java类。

但是我希望能够在 Java 应用程序中执行此操作。 (我们的想法是,我们向学生提供一个包含单元测试的应用程序。单元测试需要针对他们的代码运行,然后应用程序创建一个 JAR 文件,其中包含他们的源文件,这些文件已被测试结果“加水印”。所有这工作正常,但我们希望确保测试的类文件是从提交的源文件创建的,因此以编程方式编译 java 源的想法)。

问题在于每个学生都将他们的根包存储在任意位置,我似乎无法将文件的位置传递给 JavaCompiler (javax.tools)。

是否有可能,如果可以,有人可以提供一些提示,说明如何正确编译任意放置的根包。

干杯

理查德

更多信息:

一个学生有一个文件夹结构:

/home/student/work/java/myproject/

其中包含根包。他们启动应用程序(可能存储在此文件夹中 - 因此没有问题 - 但很可能存储在其他地方),要求他们提供包含根包的文件夹。进入后,学生点击创建 JAR 按钮,编译包中的文件,对新编译的文件运行测试,然后创建 JAR。

在考虑这个问题的同时,解决方案可能是告诉学生将我们的“create JAR”应用程序安装在包含他们的根包的文件夹中。

【问题讨论】:

  • 你不能让学生自己做 jar'ing 吗?...然后你的工具可以变成他们上传 jar 并运行测试的东西 - 这可以减轻你创建的头痛一个jar工具,并教育他们如何使用jar(我认为这很重要)
  • 另外,听起来你心目中的工具会附加某种 GUI,所以你可以给他们一个 JFileDialog 来选择源路径。

标签: java java-compiler-api


【解决方案1】:

您能否查看每个 .java 文件顶部的行首:

package com.blah.blah.assignment;

即查找包名的开头,然后在搜索路径中查找以 com 开头的第一个目录(在此示例中),然后将此路径提供给 JavaCompiler 对象,还是我误解了您的问题?

刚刚查看了 javax.tools 包,为什么不为 javaFilemanager 创建一个复合包装器,它包装了一个 ForwardingjavaFileManager,它将所有对方法的请求(例如 getFileForInput 或 getJavaFileForInput)转发到学生源目录中的相应起始目录(根据您对第一个 .java 文件的初步解析来确定其源路径的根)

【讨论】:

    【解决方案2】:

    JavaCompiler.getTask() 的最后一个参数是一个 Iterable extends JavaFileObject> 包含要传递给编译器的编译单元。提供的 JavaFileObject 实现之一是 SimpleFileJavaObject (http://java.sun.com/javase/6/docs/api/javax/tools/SimpleJavaFileObject.html)。这是用 java.net.URI 对象构造的,可以从 File 对象轻松创建。把它们放在一起,做这样的事情:

    List<JavaFileObject> javaFiles = new ArrayList<JavaFileObject>();
    File javaFile = new File(rootPackageDirFromUser, fileNameInRootDir);
    URI javaURI = javaFile.toURI();
    javaFiles.add(new SimpleJavaFileObject(javaURI, JavaFileObject.Kind.SOURCE));
    JavaCompiler.CompilationTask task =
        ToolProvider.getSystemJavaCompiler().getTask(..., javaFiles);
    

    其中 rootPackageDirFromUser 由用户给出,用户会告诉您文件存储在哪里,而 fileNameInRootDir 是该目录中 java 源文件的名称。如果您事先不知道文件名,则需要遍历 rootPackageDirFromUser 来构造一个列表。

    我没有对此进行测试,但这应该可以让您大致了解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-09
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      相关资源
      最近更新 更多