Maven:代码生成之前的部分编译

tl; dr-edition:我有一个我知道会失败的编译,但是想要编译后仍然可以在我的target/classes文件夹中编译的类的子集。 我已经配置了false ,但是没有生成类,甚至没有生成独立于除Object之外的任何其他类的虚拟类。 是否有一些配置来实现这一目标?


我有一个maven驱动的项目,其工作流程基本上包括以下(相关)目标:

  • ...
  • init-compile

    代码生成器(下面)使用基于reflection的配置,因此,在第一遍中,我想尝试尽可能多地编译项目,以便不会抛出ClassNotFoundExceptions。 此编译配置为false以便继续构建。

    不幸的是(你可以称之为设计缺陷),配置既用于代码生成(指定OWL文件和命名空间到包映射),也用于运行时,因此它还包含代码生成器不需要的其他元素,但是仍然读取,因此需要在类路径上成功。

  • generate-model

    在此步骤中,从OWL-Ontology生成一些模型类,创建使项目的其余部分完全可编译的代码。

  • default-compile

    现在,显然应该编译其余的类

  • save-model

    现在,来自本体的实例被读取并序列化为运行时的文件

  • ...

旁注:生成和保存模型都使用maven-exec-plugin ,但我真诚地认为这根本不重要。

题:

当我使用mvn -e -U clean package source:jar javadoc:jar install:install运行我的构建时mvn -e -U clean package source:jar javadoc:jar install:install ,它在generate-model目标期间失败并且我试图避免错误。 target/classes是空的,因此编译器似乎不会吐出它可以/应该能够处理的类的子集。 有没有办法实现这个目标?

我有两个解决方法,我不喜欢:

  • 在将配置文件解析为Java-Objects之前编辑配置文件“AST”,以便仅解析与代码生成器相关的部分(需要调整我可以访问的代码,但应该被我的项目认为是不可变的);
  • 并将init-compile目标配置为仅包含所需的类(太不灵活,因为POM应该/可能是使用相同模型的未来应用程序的模板)。

如果您可以想象另一种解决我的问题的方法,您可以从我的描述中看到,我也很高兴听到它们!

首先,让我重述一下你的问题,以确保我已经正确掌握了它。

  • 您有一组类,其编译forms的function是配置代码生成器和运行时。 (其中一部分与代码生成器相关,但生成将失败,除非存在完整配置。因此我们可以将其视为整个配置是必要的。)

  • 然后,您将拥有一组将作为源代码生成的类。 它们具有生成时间,可能是编译时,以及对配置类的运行时依赖性。

  • 最后,您还有一些其他代码,它们对生成的类具有编译时依赖性,并且对生成的类和配置类都有运行时依赖性。

  • 但是,您的配置类对生成的类和其他代码没有任何编译时依赖性。 您没有明确说出这一点,但我假设它,否则您会遇到循环依赖问题。

这是我的建议:将项目划分为多模块(“reactor”)项目。 您当前的项目将是反应堆项目的一个模块。 创建一个名为“config”或类似的新模块,并将配置类移入其中。 让主模块依赖它。

如果你不喜欢多模块项目,你可以通过声明一个额外执行的编译插件来实现同样的事情,绑定到generate-sources阶段。 (你没有说,但我假设你正在这个阶段进行代码生成。如果你在POM中的代码生成器插件之前声明编译插件,Maven将以相同的顺序执行它们。)你会使用编译插件的“include”filter只编译配置类。 为此,您需要将配置类放在与其他所有包都不同的包中,这无论如何都是很好的做法。

有一个非常方便的解决方案 – 使用Eclipse Java Compiler(EJC)而不是标准的Oracle javac! ECJ优于javac的一个优点是它允许出错,它会尽可能地编译并保留已经生成的文件。 EJC是为在IDE中使用而开发的,用于高度交互式工作,其中必须进行部分编译,但它也可以用作CLI或Maven插件。 Plexus家伙提供EJC作为一个方便的Maven依赖。

编译器可以在Maven中插入。 您可以在一个POM中定义多个编译(编译执行),并且可以为每个编译器使用不同的编译器,为开发人员提供广泛的选项。

示例POM代码:

  org.apache.maven.plugins maven-compiler-plugin 3.1   pre-compilation generate-sources  compile   eclipse  false     default-compile compile   compile   false      org.codehaus.plexus plexus-compiler-eclipse 2.3      org.eclipse.xtext xtext-maven-plugin 2.5.0   generate-the-stuff generate-sources  generate     

致Gabriel Axel的文章http://www.gabiaxel.com/2011/10/replacing-javac-with-eclipse-compiler.html

这种方法可以解决一些棘手的“ 生成 ”循环依赖,通过拆分成单独的模块可能无法解决。

此外,我想以最透明的方式集成源代码。 必须根据对生成的源的依赖性重新调整代码将最终破坏它。 我想基于逻辑设计对代码进行分组,而不是因为技术性问题。

如果您的代码生成器发生在xtext上,就像在我的情况下,并且您使用xtext-maven-plugin,让我们说新发布的2.5.0,您不必像上面的示例那样配置任何内容,插件就是在引擎盖。