添加自定义Java Agent后Spring Boot项目启动报错且参数调整无效
问题解决步骤
1. 修正Transformer的类过滤逻辑
你的Agent当前无差别处理所有类,这会误操作Spring Boot核心配置类,引发BeanDefinitionStoreException。必须让Transformer只针对包含@LogAdvice注解方法的业务类,同时排除Spring框架类和项目配置类。
修改LogAdviceTransformer的transform方法,添加精准过滤:
public class LogAdviceTransformer implements ClassFileTransformer { @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // 格式转换:将类路径格式转为全限定类名 String fullClassName = className.replace("/", "."); // 跳过Spring核心类、项目配置类 if (fullClassName.startsWith("org.springframework.") || fullClassName.equals("com.yourpackage.SpringBootProbeApplication")) { return null; // 不对这些类做字节码增强 } // 检查当前类是否存在带@LogAdvice的方法 try { Class<?> targetClass = loader.loadClass(fullClassName); for (Method method : targetClass.getDeclaredMethods()) { if (method.isAnnotationPresent(LogAdvice.class)) { // 执行你的字节码增强逻辑(比如ASM/ByteBuddy实现) ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = new LogAdviceClassVisitor(cw); cr.accept(cv, 0); return cw.toByteArray(); } } } catch (ClassNotFoundException e) { // 类加载失败时直接跳过 return null; } // 无目标注解方法,不处理 return null; } }
2. 解决类重复定义的LinkageError
你在premain中传入的第二个参数true,允许Transformer重新转换已加载的类,这是引发重复定义错误的核心原因。修改premain方法,只处理未加载的类:
public class ProbeAgent { public static void premain(String agentArgs, Instrumentation inst) { System.out.printf("filter class start: %d\n", System.currentTimeMillis()); LogAdviceTransformer logAdviceTransformer = new LogAdviceTransformer(); // 移除第二个参数,默认只处理未加载的类,避免重复转换 inst.addTransformer(logAdviceTransformer); System.out.printf("filter class end: %d\n", System.currentTimeMillis()); } }
3. 移除不必要的JVM参数
最初的BeanDefinitionStoreException并非模块权限问题,是Transformer误操作配置类导致的。修正过滤逻辑后,直接移除--add-opens=java.base/java.lang=ALL-UNNAMED参数,避免扩大类访问范围引发额外问题。
4. 验证Agent的MANIFEST.MF配置
确保Agent Jar的MANIFEST.MF正确指定入口,避免Agent无法被JVM识别:
Premain-Class: com.yourpackage.ProbeAgent Can-Redefine-Classes: false Can-Retransform-Classes: false
(不需要重定义/重转换类时,将后两项设为false,进一步降低冲突风险)
5. 重新打包测试
重新编译打包Agent Jar,启动Spring Boot项目时仅保留Agent参数:
java -javaagent:/path/to/Probe-Agent.jar -jar your-spring-boot-app.jar
内容的提问来源于stack exchange,提问作者Photon
相关产品推荐
相关产品推荐

