当前位置: 首页 > 知识库问答 >
问题:

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

赵智
2023-03-14

我有一个项目,它使用编译的方面并在编译时编织它们。我想添加Lombok,但不幸的是,Lombok不支持AJC。由于该项目本身没有任何方面的源代码,因此在使用Javac Lombok编译之后,我将AspectJ Maven插件配置为进行编译后编织。

以下是AspectJ Maven插件的配置:

xml prettyprint-override"><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

共有1个答案

年良骏
2023-03-14

当你在评论中问我另一个问题时,我实际上认为你的方法有问题,但它是有效的。为了直接从IDE(IntelliJ IDEA)运行测试,我必须做的唯一一件事就是将应用程序和测试运行程序委托给Maven,否则IDEA不会同时应用Lombok AspectJ。

如果你的方法有效,就使用它。但实际上AspectJ Maven建议了另一种方法:首先使用Maven编译器编译到另一个输出目录,然后使用该目录作为AspectJ编译器的weave目录。但是,那里的示例POM不能100%工作,因为在命令行上为Javac指定需要存在的输出目录时,编译器不会创建该目录。所以你也需要一些丑陋的安特伦行动:

<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. 创建一个unwoven Java模块,在那里执行Java Lombok操作

其优点是,您不需要处理多个编译器、执行阶段、输出目录、Antrun等。

更新时间:

我克隆了您的GitHub MCVE,这个对分支主机的提交反映了我在上面的示例XML中解释的内容。

我还使用另一个提交创建了一个分支多阶段编译,它根据我的另一个想法有效地重构了项目。我只是引用了提交消息:

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请求以简化操作,请告诉我。

 类似资料:
  • 问题内容: 我正在尝试使用Avro来读取和写入Kafka的邮件。有没有人有使用Avro二进制编码器对将放入消息队列中的数据进行编码/解码的示例? 我需要的是Avro而不是Kafka。或者,也许我应该考虑其他解决方案?基本上,我试图在空间方面找到一种更有效的JSON解决方案。刚刚提到了Avro,因为它可以比JSON紧凑。 问题答案: 我终于想起要询问Kafka邮件列表,并得到以下答复,效果很好。 是

  • 问题内容: 我在LibGdx Stage对象中对Actor排序时遇到麻烦。渲染舞台后,将按照添加顺序渲染图像。舞台使用数组来保存演员。我尝试设置每个Actor的ZIndex,但仍然没有排序。然后我尝试创建一个比较器对象,如下所示: 然后当我想进行实际比较时,我做了: 它给了我以下错误,将无法编译: 我不知道我在做什么错。谁可以给我解释一下这个? 问题答案: 看起来您的代码返回的是而不是。 方法仅接

  • 问题内容: 我正在开发Angular Web应用程序的i18n部分,我想在配置阶段使用angular-translate。 我定义了一些我想翻译的数据: 这是我的配置声明: 我得到的错误是经典 错误 : 错误:[$ injector:unpr]未知提供程序:$ filter 我知道我不能在配置阶段使用服务,只能在提供程序中使用,但是我的问题有解决方案吗? 编辑: 我的问题已经解决,方法是将键 ‘t

  • 本文向大家介绍使用base64对图片的二进制进行编码并用ajax进行显示,包括了使用base64对图片的二进制进行编码并用ajax进行显示的使用技巧和注意事项,需要的朋友参考一下 使用base64对图片的二进制进行编码并用ajax进行显示 有时候我们需要动态的将图片的二进制在页面上进行显示,如我们需要弄一个验证码的功能,那么如果我们的验证码的图片在后台得到的是该图片的二进制,那么当我们需要在页面上

  • 我正在尝试使用BigInteger类从二进制数打印十进制数。我正在使用BigInteger类的BigInteger(String val,int radix)构造函数将给定的二进制值转换为十进制值,但它打印的是构造函数中传递的精确二进制值。WAHT是错误吗?代码如下:

  • 问题内容: 我从事Web编程已经有几年了,自那时以来,我还没有为桌面应用程序做任何编程,而且我已经忘记了很多事情。如果这太简单,请耐心等待。 现在我有这种情况: 我正在尝试将一些散列字存储在文件中。我想我应该为此使用二进制文件(如果我错了,请纠正我)。但是我不知道如何将单词写到文件中。我尝试了很多方法,但是当我读回文件并尝试解密单词时,我得到了。 有谁知道如何将单词写到文件中? PS:我使用以下代