如何用Gradle将AspectJ织入外部JAR?代码无报错但未生效排查
如何通过build.gradle将AspectJ织入外部JAR
我需要用AspectJ的@Around注解替换外部JAR(j2mod库)中的方法,环境为Java 11、Gradle 7.1.1。目前使用GPT-4生成的构建脚本能成功构建执行,但切面并未织入到j2mod中,以下是原配置和切面代码,求分析问题并解决。
原build.gradle配置
plugins { id 'io.freefair.aspectj' version '6.2.0' } apply plugin: 'io.freefair.aspectj' bootJar { launchScript() } dependencies { implementation 'org.aspectj:aspectjrt:1.9.7' implementation 'com.ghgande:j2mod:3.1.1' } configurations { aspectpath inpath } def j2modJar = configurations.runtimeClasspath.files.find { it.name.contains('j2mod') } dependencies { aspectpath 'org.aspectj:aspectjtools:1.9.7' inpath files(j2modJar) } def weavedClassesDir = "$buildDir/weaved-classes" task weave(type: JavaExec) { main = 'org.aspectj.tools.ajc.Main' classpath = configurations.aspectpath + configurations.compileClasspath args = [ '-inpath', configurations.inpath.asPath, '-aspectpath', sourceSets.main.output.asPath, '-d', weavedClassesDir, '-source', '11', '-target', '11', '-showWeaveInfo' ] doFirst { new File(weavedClassesDir).mkdirs() } } compileJava.finalizedBy(weave) task buildWeavedJar(type: Jar, dependsOn: weave) { from zipTree(weavedClassesDir) archiveClassifier.set('weaved') destinationDirectory.set(file("$buildDir/libs")) } assemble.dependsOn buildWeavedJar
原切面代码
@Aspect public class ExampleAdvice { @Around("execution(* com.ghgande.j2mod.modbus.msg.WriteMultipleRegistersRequest.createResponse(..))") public ModbusResponse exampleAdvice(ProceedingJoinPoint pjp) { // make desirable return value return response; } }
问题分析
- 插件与手动任务冲突:已经引入
io.freefair.aspectj插件,该插件已封装AspectJ织入逻辑,手动创建weave任务属于重复处理,且插件流程可能覆盖手动任务结果。 - inpath配置不规范:手动获取j2mod JAR并添加到inpath的方式,未被Freefair插件的织入流程识别,外部JAR未被纳入织入范围。
- 织入结果未生效:生成的带
weaved分类器的JAR未被bootJar任务使用,最终运行的仍是未织入的原始依赖。 - 版本兼容性问题:手动指定的AspectJ 1.9.7与Freefair插件6.2.0的默认适配版本存在潜在冲突。
修正后的build.gradle配置
plugins { id 'io.freefair.aspectj' version '6.2.0' id 'org.springframework.boot' version '2.6.7' // 根据实际Spring Boot版本调整 id 'io.spring.dependency-management' version '1.0.11.RELEASE' } bootJar { launchScript() // 确保织入后的类被打包到最终运行的Boot JAR from sourceSets.main.output } dependencies { implementation 'org.aspectj:aspectjrt' implementation 'com.ghgande:j2mod:3.1.1' // 使用插件专用配置指定需要织入的外部JAR aspectInpath 'com.ghgande:j2mod:3.1.1' } // 配置AspectJ编译参数,开启织入信息便于调试 aspectj { sourceCompatibility = 11 targetCompatibility = 11 ajcOptions { option '-showWeaveInfo' } }
修正后的切面代码(Spring环境下)
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import com.ghgande.j2mod.modbus.msg.ModbusResponse; import com.ghgande.j2mod.modbus.msg.WriteMultipleRegistersResponse; @Aspect @Component // Spring项目需添加该注解让容器扫描到切面 public class ExampleAdvice { @Around("execution(* com.ghgande.j2mod.modbus.msg.WriteMultipleRegistersRequest.createResponse(..))") public ModbusResponse exampleAdvice(ProceedingJoinPoint pjp) throws Throwable { // 自定义拦截逻辑 System.out.println("成功织入,拦截到createResponse方法"); // 若需执行原方法,调用pjp.proceed() // ModbusResponse originalResponse = (ModbusResponse) pjp.proceed(); // 构造自定义响应 ModbusResponse response = new WriteMultipleRegistersResponse(); // 设置响应参数 return response; } }
内容的提问来源于stack exchange,提问作者o1iveleaves
相关产品推荐
相关产品推荐

