Intellij + Ajc + Lombok/Mapstruct

9
我想在我的IntelliJ Idea中启用AspectJ编译器,因为我有几个方面需要在编译时编织。
同时,我正在使用Lombok和Mapstruct在我的代码库中。
这两种工具都需要进行额外的注释处理,必须在ajc开始之前完成。我已经安装了Lombok和Mapstruct的插件。分别使用它们是可以正常工作的,源代码也被生成。但是当我启用ajc并勾选启用注释处理选项后,构建项目时会出现以下错误:
Error:(9, 0) ajc: Internal error in the mapping processor: java.lang.NullPointerException   at org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding.sourceField(FieldBinding.java:425)     at org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl$SourceLocationComparator.determineSourceStart(TypeElementImpl.java:108)      at org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl$SourceLocationComparator.getSourceStart(TypeElementImpl.java:72)     at org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl$SourceLocationComparator.compare(TypeElementImpl.java:65)    at org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl$SourceLocationComparator.compare(TypeElementImpl.java:1)     at java.util.TimSort.countRunAndMakeAscending(TimSort.java:360)     at java.util.TimSort.sort(TimSort.java:234)     at java.util.Arrays.sort(Arrays.java:1512)      at java.util.ArrayList.sort(ArrayList.java:1462)    at java.util.Collections.sort(Collections.java:175)     at org.aspectj.org.eclipse.jdt.internal.compiler.apt.model.TypeElementImpl.getEnclosedElements(TypeElementImpl.java:166)    at org.mapstruct.ap.internal.util.workarounds.SpecificCompilerWorkarounds.replaceTypeElementIfNecessary(SpecificCompilerWorkarounds.java:99)    at org.mapstruct.ap.internal.util.Executables.getAllEnclosedExecutableElements(Executables.java:99)     at org.mapstruct.ap.internal.model.common.Type.getAllMethods(Type.java:633)     at org.mapstruct.ap.internal.model.common.Type.getPropertyReadAccessors(Type.java:496)      at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.build(BeanMappingMethod.java:168)      at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMappingMethods(MapperCreationProcessor.java:376)      at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMapper(MapperCreationProcessor.java:151)      at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:122)    at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:76)     at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:283)     at org.mapstruct.ap.MappingProcessor.processMapperTypeElement(MappingProcessor.java:263)    at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:221)   at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:156)     at org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:139)     at org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.round(RoundDispatcher.java:121)   at org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager.processAnnotations(BaseAnnotationProcessorManager.java:159)    at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.processAnnotations(Compiler.java:931)     at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:437)    at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:417)    at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:1036)   at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performBuild(AjBuildManager.java:272)      at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:185)    at com.intellij.lang.aspectj.build.AjJpsCompiler.doBuild(AjJpsCompiler.java:249)    at com.intellij.lang.aspectj.build.AjJpsCompiler.build(AjJpsCompiler.java:119)      at com.intellij.lang.aspectj.build.AjTranslatingBuilder.doBuild(AjTranslatingBuilder.java:114)      at com.intellij.lang.aspectj.build.AjBuilderBase.build(AjBuilderBase.java:74)   at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1328)      at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1008)     at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1075)   at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:969)     at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:798)      at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:380)     at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:178)    at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:139)     at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:302)   at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:135)    at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:228)   at org.jetbrains.jps.service.impl.SharedThreadPoolImpl.lambda$executeOnPooledThread$0(SharedThreadPoolImpl.java:42)     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)      at java.util.concurrent.FutureTask.run(FutureTask.java:266)     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)      at java.lang.Thread.run(Thread.java:748)  

此外,我看到了其他一堆ajc编译错误,因为它无法定位应该由Lombok生成的方法。
我该如何解决这些问题?

你使用的是哪个版本的acj?你的构建工具是否有相同的问题? - Filip
/aspectj/aspectjtools/1.8.13/aspectjtools-1.8.13.jar - Ihor M.
3个回答

5

你好,我遇到过类似的问题。

解决方法是让aspectj-maven-plugin在类编译完成后才开始织入。

在此处有更详细的说明:https://www.mojohaus.org/aspectj-maven-plugin/examples/weaveDirectories.html

我需要做以下几步:

(1) 通过<weaveDirectories >指定已编译类所在的文件夹

(2) 将maven-compiler-plugin生命周期的阶段更改为“process-classes”或更晚的阶段。

这是我的pom文件的样子。

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${mapstruct.version}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${org.projectlombok.version}</version>
                    </path>
                </annotationProcessorPaths>
                <compilerArgs>
                    <compilerArg>-Amapstruct.defaultComponentModel="spring"</compilerArg>
                    <compilerArg>-Amapstruct.unmappedTargetPolicy=ERROR</compilerArg>
                    <compilerArg>-Amapstruct.suppressGeneratorTimestamp=true</compilerArg>
                    <compilerArg>-Amapstruct.suppressGeneratorVersionInfoComment=true</compilerArg>
                </compilerArgs>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <configuration>
                <showWeaveInfo>${showWeaveInfo}</showWeaveInfo>
                <showWeaveInfo>true</showWeaveInfo>
                <Xlint>ignore</Xlint>
                <complianceLevel>${java.compiler.version}</complianceLevel>
                <encoding>UTF-8</encoding>
                <verbose>false</verbose>
                <verbose>true</verbose>
                <forceAjcCompile>true</forceAjcCompile>
                <sources/>
                <weaveDirectories>
                    <weaveDirectory>${project.build.directory}/classes</weaveDirectory>
                </weaveDirectories>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>com.lib.test</groupId>
                        <artifactId>test1</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>com.lib.test2</groupId>
                        <artifactId>test2</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
            </configuration>
            <executions>
                <execution>
                    <phase>process-classes</phase>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

由于您提供的设置,测试未能正确编译。[错误] 方法getAList()在类型TransactionalIT.ObjectGraph中未定义 ...transactional/NestedTransactionsJdbcDao.java:26 createEntitiesA(og.getAList()); - Ihor M.
这里有什么部分是罪魁祸首的想法吗? - Ihor M.
这是我看到的错误:Error:(18, 0) ajc: 源参数中不存在名为"contentType"的属性。你是想说"createdTime"吗? 这是由于lombok处理器没有被调用引起的。我已经尝试过配置,但没有成功。 - Ihor M.
以下是在该错误之前出现的警告:警告:ajc:您未使用lombok支持的编译器,因此lombok将无法工作并已被禁用。 您的处理器是:org.aspectj.org.eclipse.jdt.internal.compiler.apt.dispatch.BatchProcessingEnvImpl Lombok支持:sun/apple javac 1.6、ECJ - Ihor M.
1
我认为在GitHub上发布一个MCVE是有意义的,这样可以让我们重现和分析你的问题。 - kriegaex
好的例子,使用了3个注解处理器:lombok、mapstruct和aspectj。我按照这里的指示进行操作,编译了来自aspectj插件和其他类似问题的信息,并且它可以正常工作。关键在于让aspectj编织生成的类,不干扰mapstruct和aspectj处理器进行代码生成。 - WinterBoot

4

0
如果您在同一项目中有方面源代码,那么您应该根据@jun-huh的答案添加几行代码,并删除<aspectLibraries>。下面的pom.xml是用于在同一项目中使用方面的情况。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>az.sanco</groupId>
    <artifactId>aspect</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.14.0</version>
                <configuration>
                    <forceAjcCompile>true</forceAjcCompile>
                    <weaveDirectories>
                        <weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
                    </weaveDirectories>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                    <proc>none</proc><!-- annotation process already finished, so we don't need to run again-->
                </configuration>
                <executions>
                    <execution>
                        <id>copy-only-aspect-files</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <!--when `javac` compile works it does not copy *.aj files to the 
                            output directory. We need to run `ajc` compile during `compile` phase and 
                            copy only *.aj files to weave our classes-->
                            <includes>
                                <include>**/*.aj</include><!--IMPORTANT-->
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接