如何在Javac + Lombok阶段之后使用ANOJ Maven进行二进制编织

kokeuurv  于 11个月前  发布在  Maven
关注(0)|答案(1)|浏览(130)

我有一个项目,它使用编译的方面,并在编译时编织它们。我想添加Lombok,但不幸的是Lombok不支持AJC。由于这个项目本身没有任何方面的来源,我配置了AJC J Maven插件来做编译后编织,在用Javac+Lombok编译后。
下面是ANOW J Maven插件的配置:

<forceAjcCompile>true</forceAjcCompile>
<sources/>
<weaveDirectory>${project.build.outputDirectory}</weaveDirectory>

字符串
它在Maven编译器插件编译之后被附加到编译阶段。这样,Lombok + Javac将首先被调用,然后AJC将在Javac生成的类文件上执行编织。
在javac生成的类上执行字节码编织时有什么限制/缺点吗?
也许有一种更好的方法可以让Maven+Lombok+Aspects+Idea一起工作而不出问题。
下面是一个最小的示例项目:https://github.com/Psimage/aspectj-and-lombok

svmlkihl

svmlkihl1#

当你在评论中问我另一个问题时,我实际上认为你的方法有问题,但它是有效的。为了直接从IDE(IntelliJ IDEA)运行测试,我必须做的唯一一件事就是将应用程序和测试运行器委托给Maven,因为否则IDEA不会同时应用Lombok + AIDEA J。
x1c 0d1x的数据
如果你的方法有效,就使用它。但实际上,ANOJ Maven建议使用another approach:首先用Maven编译器编译到另一个输出目录,然后将该目录用作AZeroJ编译器的weave目录。不过,那里的示例POM并不能100%工作,因为当在命令行上为Javac指定输出目录时,该目录需要存在,它不会被编译器创建。所以你还需要一些丑陋的Antrun操作:

<plugins>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
      <execution>
        <id>unwovenClassesFolder</id>
        <phase>generate-resources</phase>
        <configuration>
          <tasks>
            <delete dir="${project.build.directory}/unwoven-classes"/>
            <mkdir dir="${project.build.directory}/unwoven-classes"/>
          </tasks>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
      <execution>
        <!-- Modifying output directory of default compile because non-weaved classes must be stored
             in separate folder to not confuse ajc by reweaving already woven classes (which leads to
             to ajc error message like "bad weaverState.Kind: -115") -->
        <id>default-compile</id>
        <configuration>
          <compilerArgs>
            <arg>-d</arg>
            <arg>${project.build.directory}/unwoven-classes</arg>
          </compilerArgs>
        </configuration>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <configuration>
      <aspectLibraries>
        <aspectLibrary>
          <groupId>me.yarosbug</groupId>
          <artifactId>aspects</artifactId>
        </aspectLibrary>
      </aspectLibraries>

      <forceAjcCompile>true</forceAjcCompile>
      <sources/>
      <weaveDirectories>
        <weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory>
      </weaveDirectories>
    </configuration>
    <executions>
      <execution>
        <phase>process-classes</phase>
        <goals>
          <goal>compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
  </plugin>

</plugins>

字符串
我建议另一种方法作为替代:
1.创建一个非编织的Java模块,在那里做Java + Lombok的事情。
1.使用Java模块作为weave依赖项,创建一个单独的模块来进行AjaxJ二进制织入。因为您的单元测试同时依赖于Lombok和AjaxJ,所以将测试放在这个模块中。
优点是你不需要摆弄多个编译器,执行阶段,输出目录,Antrun等。

更新:

我克隆了你的GitHub MCVEthis commit on branch master反映了我在上面的示例XML中解释的内容。
我还用another commit创建了一个branch multi-phase-compilation,它根据我的替代想法有效地重构了项目。我只是引用提交消息:

Multi-phase compilation: 1. Java + Lombok, 2. AspectJ binary weaving

There are many changes (sorry, I should have split them into multiple
commits):
  - Marker annotation renamed to @marker and moved to separate module
    because the main application should not depend on the aspect module.
    Rather both application and aspect now depend on a common module.
  - New module "main-app-aspectj" does only AspectJ binary weaving on
    the already lomboked Java application.
  - Both application modules have slightly different unit tests now: One
    checks that Lombok has been applied and AspectJ has not, the other
    checks that both have been applied.
  - Aspect pointcut limits matching to "execution(* *(..))" in order to
    avoid also matching "call()" joinpoints.

The end result is that now we have a clear separation of concerns, clear
dependencies, no more scripted Ant build components and the new option
to use the lomboked code optionally with or without aspects applied
because both types or JARs are created during the build.


请随意将我的fork作为另一个远程添加到您的Git存储库中,并从那里拉入我的更改。如果您希望我向您发送pull请求以使其更容易,请告诉我。

更新2,2023-12-16:

我重新审视这个主题的另一个原因,并意识到,上次我没有提到一件重要的事情:在一个多模块方法中,有一个中间的非编织模块和一个最终的编织模块,前者应该在后者中声明为provided作用域,因为我们希望避免非编织模块最终出现在依赖于编织模块的其他模块的类路径上。这很重要,因为否则两组(重复的,但不同的)类将在类路径上结束,并且取决于确切的类加载情况,可以首先找到任何一个。
因此,我将a few commits添加到多模块分支中,清理了这种情况,并添加了一个依赖模块,对类路径内容进行了测试,以确保一切都能按预期工作。

相关问题