我有一个使用已编译方面的项目,并在编译时进行编织。我想添加Lombok,但是不幸的是Lombok不支持AJC。由于该项目本身没有任何方面的资源,因此在使用Javac + Lombok进行编译之后,我将AspectJ Maven插件配置为进行后编译编织。
这是AspectJ Maven插件的配置:
<forceAjcCompile>true</forceAjcCompile>
<sources/>
<weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
它在Maven Compiler插件编译之后立即附加到编译阶段。这样,将首先调用Lombok + Javac,然后再由AJC对Javac生成的类文件进行编织。
在javac生成的类上执行字节码编织时,是否存在任何限制/缺点?
也许有更好的方法可以使Maven + Lombok + Aspects + Idea协同工作而没有问题。
这是一个最小的示例项目:https://github.com/Psimage/aspectj-and-lombok
答案 0 :(得分:0)
在另一个问题中,当您在评论中问我时,我实际上以为您的方法有问题,但它是有效的。为了直接从IDE(IntelliJ IDEA)直接运行测试,我要做的唯一一件事就是实际上将应用程序和测试运行程序委托给Maven,因为否则IDEA不会同时应用Lombok + AspectJ。
如果您的方法可行,请使用它。但是实际上AspectJ Maven建议使用another approach:首先使用Maven编译器编译到另一个输出目录,然后使用该目录作为AspectJ编译器的编织目录。但是,这里的示例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>
我建议使用另一种方法替代
优点是您无需费心处理多个编译器,执行阶段,输出目录,Antrun等。
更新:
我克隆了您的GitHub MCVE,this commit on branch master反映了我在上面的示例XML中所解释的内容。
我还用branch multi-phase-compilation创建了一个another commit,可以根据我的替代想法有效地重构项目。我只是引用提交消息:
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存储库,并从那里提取我的更改。如果您希望我发送拉取请求以便于您轻松进行操作,请告诉我。