如何获取编译器编译一个类所需的所有源列表

时间:2013-06-22 11:21:00

标签: java java-compiler-api

要在运行时创建和加载类,我首先从数据库中读取其内容,创建一个新的 SimpleJavaFileObject ,最后通过将其传递给 CompilationTask 。 关键是这个新文件可能引用其他文件(直接导入或“间接”通过de.package。*),这些文件也存储在数据库中,不能作为类或源代码文件使用。

public class Test1 {
     public de.otherpackage.Test2 reply() {
          return null;
     }
}

与Test1一样,我必须先创建和编译Test2,因为没有 JavaFileObjects 或类来为编译器提供数据。

那么:如何获得编译器编译一个类所需的所有源列表?

知道Test1需要Test2就足够了。我首先通过将 Processor 传递给 CompilationTask 来尝试它。我检查了树中的所有属性,但没有发现任何有用或完整的内容。如果在包上使用*导入类,则无法获得完全限定名称...至少不适合我: - /

有什么想法吗?也许有更好的方法来解析javasources?

感谢您的帮助: - )

1 个答案:

答案 0 :(得分:0)

如果您在之前询问是否有办法编译课程,那么答案是“No there not”。源代码和源代码单独确定直接依赖性。并且您需要编译源代码以便提取它们。

如果您在编译时或编译后询问是否有提取依赖关系的方法,那么有几种选择:

  • javac命令有-verbose选项,导致它列出每个加载的类,并编译每个文件。

  • 如果使用标准编译器API,它会提供用于加载依赖类和查找源文件的挂钩。您可以使用它们来跟踪正在发生的事情。

  • 您可以从字节码文件本身获取大部分此类信息。但有几点需要注意:

    • 如果代码是使用-g:none编译的,则“.class”文件中不会有源文件名。

    • 您可以确定依赖关系,但不会记录编译时间...除非您可以从文件时间戳推断它们。

    • 在编译时完全解析(并内联)对另一个类中声明的编译时常量的依赖...并且在生成的“.class”文件中不会有任何跟踪。

但请注意,您通常不需要 来编译类。如果编译器发现它需要加载或编译依赖类,它会自动执行。至少,这是javac默认行为的方式。