AspectJ整合Lombok时handler切点不支持异常排查方案咨询
AspectJ+Lombok场景下handler切点不支持异常排查方案
异常背景
项目使用aspectj-maven-plugin做编译期织入时,运行抛出异常:
org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException: Pointcut expression 'handler(*) && args(e)' contains unsupported pointcut primitive 'handler'
无Lombok的项目执行常规Build/Rebuild可正常完成织入,引入Lombok后,按空<sources/>+forceAjcCompile=true的原地织入方案配置后仍报上述错误。
问题1:为什么常规编译期织入模式在无Lombok场景下能正常运行
handler是AspectJ独有的切点原语,作用是匹配代码中的catch异常处理块,该切点的匹配逻辑依赖源码级语法树解析:
- 常规Build的默认模式下,
aspectj-maven-plugin会调用ajc编译器直接替代javac接管所有.java源文件的编译全流程,ajc在解析源码语法树阶段就能直接识别所有catch块结构,自然可以正常解析、织入handler切点对应的逻辑。 - 无Lombok场景下不存在额外的代码生成步骤,ajc拿到的源码就是完整的业务代码,全量编译+织入流程没有断点,所以不会报切点不支持的错误。
问题2:开启原地织入时缺失了哪些环节导致织入失败
你配置的空<sources/>+指定weaveDirectories为target/classes的模式,本质是二进制织入:ajc不再处理.java源码,只对javac编译完成(含Lombok注解处理生成的代码)后的.class文件做字节码增强,这个流程相比常规源码编译织入缺了三个核心必要条件:
- 缺失源码语法树输入:老版本AspectJ(1.8.x系列)的二进制织入逻辑,只支持从源码语法树识别handler切点,不支持从编译后的class文件异常表反向匹配catch块结构,直接判定handler为不支持的切点原语。
- 版本与配置不匹配:当前使用的aspectj 1.8.9、aspectj-maven-plugin 1.10版本本身就没有实现二进制织入场景下的handler切点支持,同时配置里重复定义
<verbose>标签、将<Xlint>设为ignore屏蔽了织入阶段的告警,无法提前发现切面加载、类路径缺失的问题。 - 切面加载路径缺失:配置中没有显式声明所有包含切点定义的切面依赖,ajc在织入时无法正确加载切点表达式,直接触发不支持原语的报错。
问题3:AspectJ结合Lombok场景下的异常解决方案
按照以下步骤调整配置即可解决:
- 统一升级AspectJ版本
将插件依赖、项目依赖中所有aspectj相关包(aspectjrt、aspectjweaver、aspectjtools)的版本统一升级到1.9.7及以上,该版本后正式支持二进制织入模式下从字节码异常表识别handler切点,不要继续使用1.8.x老版本。 - 调整编译流程顺序,确保Lombok代码生成在织入前完成
配置maven-compiler-plugin显式声明Lombok为注解处理器,确保javac编译阶段就完成所有Lombok代码生成,输出到target/classes的class文件是完整的业务字节码:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>1.8</source> <target>1.8</target> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </path> </annotationProcessorPaths> </configuration> </plugin> - 修正aspectj-maven-plugin配置
升级插件版本到1.14.0,保留Lombok兼容的核心配置,同时开启字节码织入所需的参数,显式声明所有切面依赖:<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <configuration> <showWeaveInfo>true</showWeaveInfo> <source>1.8</source> <target>1.8</target> <complianceLevel>1.8</complianceLevel> <encoding>UTF-8</encoding> <Xlint>warning</Xlint> <outxml>true</outxml> <forceAjcCompile>true</forceAjcCompile> <reweavable>false</reweavable> <XhasMember>true</XhasMember> <!-- Lombok兼容核心配置 start --> <sources/> <weaveDirectories> <weaveDirectory>${project.build.directory}/classes</weaveDirectory> </weaveDirectories> <!-- Lombok兼容核心配置 end --> <!-- 所有包含@Aspect切面的依赖都要在这里声明 --> <aspectLibraries> <aspectLibrary> <groupId>software.amazon.lambda</groupId> <artifactId>powertools-logging</artifactId> </aspectLibrary> </aspectLibraries> </configuration> <executions> <execution> <phase>process-classes</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>1.9.7</version> </dependency> </dependencies> </plugin> - 本地IDE构建配置调整
如果使用IDEA本地开发,需要将构建运行方式切换为Maven,不要使用IDEA自带的编译器做Build/Rebuild,避免跳过process-classes阶段导致ajc织入逻辑不执行。
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

