如何在生成.class文件之前运行进程

时间:2018-12-09 23:53:43

标签: java compilation

我有与我试图用模板模型替换的创建/更新/删除API几乎相同的代码。

因此,我在文本模板中定义了控制器代码,然后在应用程序启动时尝试将模板复制到我的项目目录中,并用实际值替换变量以生成具有相应类名的API。

然后,当我需要进行更改时,可以更改模板而不是每个API,以减少总体代码维护。复制功能正在运行,但是在生成.class文件之后才发生。意味着我的应用程序实际使用的代码始终是当前版本之后的一个版本。

为了使我能够运行正确的版本,我需要在不更改模板的情况下再次重新启动应用程序。这样,当前版本和先前版本将完全相同,并且似乎可以正常工作。

但是,从生产的角度来看,这不是很方便。我尝试使用javax.tools。*来编译代码,但是因为我在应用程序内部使用了许多依赖关系,否则除非我可以将我的项目一起编译(包括需要生成的文件),否则它将失败。

src\main\java\com\project\dao\model\User.java:3: error: package com.vividsolutions.jts.geom does not exist
import com.vividsolutions.jts.geom.Point;
                                  ^
src\main\java\com\project\dao\model\User.java:5: error: package javax.persistence does not exist
import javax.persistence.*;

是否可以:

  1. 在生成.class文件之前创建文件,以便可以将项目一起编译。如果模板有错误或提供了无效变量,则会抛出编译错误。

  2. 在应用程序完全可用之前自动将其重新启动。这样,代码将启动并从模板生成文件。然后它将关闭。然后它将再次自动重新启动并识别新生成的文件,以便可以将项目一起编译。

1 个答案:

答案 0 :(得分:0)

您可以通过将依赖关系一分为二来实现。换句话说,模板生成器不应依赖于它生成的类。

这意味着您不应在模板生成器代码中的任何位置导入模板生成的类。

编译完类后,请使用Class.forName("path.to.my.generated.class.Getter");实例化生成的类。

这里的经验法则是:对于任何要加载的类,所有其声明的导入  首先加载。为避免那样加载依赖项,请使用Class.forName(),它会在调用时加载该类。

注意:所有异常/错误处理都被忽略了。

class MyCodeGenerator {
    public void main(String[] args) {
        generateCode();
        Class getterClass = Class.forName("path.to.my.generated.class.Getter");
        Object getter = getterClass.newInstance();
        Method initMethod = getterClass.getMethod("init");
        initMethod.invoke(getter);
    }
}

class Getter {
    public void init() {
        ...
    }
}