1

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

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

像 Test1 一样,我必须提前一步创建和编译 Test2,因为没有JavaFileObjects或类可以提供给编译器。

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

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

有任何想法吗?也许有更好的方法来解析javasources?

感谢您的帮助:-)

4

1 回答 1

0

如果您在编译类之前询问是否有办法做到这一点,那么答案是“不,没有”。源代码,而源代码本身就决定了直接的依赖关系。您需要编译源代码才能提取它们。

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

  • javac命令有一个-verbose选项,可以列出每个加载的类和编译的每个文件。

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

  • 您可以从字节码文件本身获得大部分信息。不过有几点需要注意:

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

    • 您可以通过不记录编译时间来确定依赖关系......除非您可以从文件时间戳中推断出它们。

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

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

于 2013-06-22T12:37:11.473 回答