You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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;
    }
}

问题分析

  1. 插件与手动任务冲突:已经引入io.freefair.aspectj插件,该插件已封装AspectJ织入逻辑,手动创建weave任务属于重复处理,且插件流程可能覆盖手动任务结果。
  2. inpath配置不规范:手动获取j2mod JAR并添加到inpath的方式,未被Freefair插件的织入流程识别,外部JAR未被纳入织入范围。
  3. 织入结果未生效:生成的带weaved分类器的JAR未被bootJar任务使用,最终运行的仍是未织入的原始依赖。
  4. 版本兼容性问题:手动指定的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:07:03