无法为 AspectJ 添加 javaagent
Can't add javaagent for AspectJ
我有一个旧的 Java6 应用程序,我正在尝试添加一些自动和全局日志来跟踪每个方法中的每个调用。
它 运行s 在 JBoss 4.2.3.
我有我的个人资料 class :
package com.al6.borneIntranet.business.log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;
import org.springframework.core.annotation.Order;
@Aspect
public class ProfilingAspect {
@Around("methodsToBeProfiled()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
StopWatch sw = new StopWatch(getClass().getSimpleName());
try {
sw.start(pjp.getSignature().getName());
return pjp.proceed();
} finally {
sw.stop();
System.out.println(sw.prettyPrint());
}
}
@Pointcut("execution(public * com.al6.borneIntranet..*.*(..))")
public void methodsToBeProfiled(){}
}
我创建了一个 META-INF/aop.xml 文件:
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.al6.*"/>
</weaver>
<aspects>
<!-- weave in just this aspect -->
<aspect name="com.al6.borneIntranet.business.log.ProfilingAspect"/>
</aspects>
</aspectj>
我在我的 bean 定义中添加了这一行 xml :
<context:load-time-weaver/>
我有这个依赖关系:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
它几乎可以工作,但我在使用该应用程序时在启动时出现此错误:
2021-04-29 18:41:46,960 ERROR [STDERR] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.jboss.mx.loading.UnifiedClassLoader3] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
我从 Maven 存储库下载 spring-instrument-4.0.6.RELEASE.jar 文件,然后在 运行 启动脚本中添加 javaagent 部分:
/opt/jdk/bin/java -Dprogram.name=run.sh -javaagent:/opt/jboss/lib/org.springframework.instrument.jar -server -Xms2048m -Xmx2048m -XX:MaxPermSize=256M ...
但是还是报错,像什么都没做一样
有没有办法在启动时轻松不添加此选项?
为什么即使我添加了它也没有被使用?
编辑:
我尝试添加 adspectj 启动代理,但也没有用,同样的错误,应用程序似乎未检测到该选项:
/bin/sh /opt/jboss/bin/run.sh -c commandes -b 0.0.0.0 -Djboss.partition.name=jboss-commande-preprod1-partition
admin 22263 47.6 76.7 4911056 4023536 pts/0 Sl 16:03 2:14 /opt/jdk/bin/java -Dprogram.name=run.sh -javaagent:/opt/jboss/lib/aspectjweaver-1.8.9.jar -javaagent:/opt/jboss/lib/org.springframework.instrument.jar -server -Xms3500m -Xmx
3500m -XX:MaxPermSize=512M -Dfile.encoding=UTF-8 -Djava.awt.headless=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dc
om.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -XX:+UseG1GC -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -Djava.net.prefer
IPv4Stack=true -Djava.endorsed.dirs=/opt/jboss/lib/endorsed -classpath /opt/jboss/bin/run.jar:/opt/jdk/lib/tools.jar org.jboss.Main -c commandes -b 0.0.0.0 -Djboss.partition.name=jboss-commande-preprod1-partition
编辑 2:
尝试一些事情:
使用 Jboss timeweaver :
创建名为 'loadTimeWeaver' 的 bean 时出错:bean 实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 bean class [org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver]:构造函数抛出异常;嵌套异常是 java.lang.IllegalStateException: 无法初始化 JBoss LoadTimeWeaver 因为 JBoss 6 API classes 不可用
当然,我在 Jboss 4.3.2
- 在 aop.xml 中添加“-verbose -showWeaveInfo -debug”:
文件被检测到,因为我在启动时有这些行:
2021-05-03 15:11:42,267 ERROR [STDERR] [UnifiedClassLoader3@341a736] info AspectJ Weaver Version 1.8.9 built on Monday Mar 14, 2016 at 21:18:16 GMT
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register classloader org.jboss.mx.loading.UnifiedClassLoader3@341a736
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info using configuration file:/opt/jboss-4.2.3.GA/server/weldom_commandes/tmp/deploy/tmp6458410370486804467BorneIntranetServeurMetier.ear-contents/BorneIntranetServeurMetier.jar!/META-INF/aop.xml
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info using configuration file:/opt/jboss-4.2.3.GA/server/weldom_commandes/tmp/deploy/tmp6458410370486804467BorneIntranetServeurMetier.ear-contents/spring-aspects-4.0.6.RELEASE.jar!/META-INF/aop.xml
2021-05-03 15:11:43,259 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect com.al6.borneIntranet.business.log.ProfilingAspect
2021-05-03 15:11:43,474 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
2021-05-03 15:11:43,520 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
2021-05-03 15:11:43,536 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
2021-05-03 15:11:43,544 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
2021-05-03 15:11:43,559 ERROR [STDERR] [UnifiedClassLoader3@341a736] debug not weaving 'com.al6.borneIntranet.business.ServiceArchiveEntryPointBean'
...
当我输入时:
<context:load-time-weaver
weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
我的错误略有不同,但结果相同:
2021-05-03 15:15:03,475 ERROR [STDERR] java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
2021-05-03 15:15:03,476 ERROR [STDERR] at org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver.addTransformer(InstrumentationLoadTimeWeaver.java:88)
但我已经添加了它:
-javaagent:/opt/jboss/lib/org.springframework.instrument.jar
ls -lrt /opt/jboss/lib :
-rwxrwxrwx 1 admin users 7244 2021-04-30 16:03 /opt/jboss/lib/org.springframework.instrument.jar*
我不是 Spring 用户,但是在这里回答 AspectJ LTW 问题时,我经常注意到 Spring 文档之间存在一定的差异,提到需要 Spring Instrument Java 仅代理,在实际情况下可以像这样配置 Spring,但这很棘手。到目前为止最简单的方法是将 AspectJ Weaver 代理也添加到命令行,即使用类似的东西(当然是在一行上)
# AspectJ LTW
-javaagent:/path/to/aspectjweaver.jar
# Spring Instrument
-javaagent:/path/to/org.springframework.instrument.jar
也许 AspectJ Weaver 已经足够了,这取决于您的用例。
更新 在 OP 更新他的问题后:
- 您是否在您的应用程序服务器日志中看到正在加载 AspectJ weaver 的任何迹象?扫描
AspectJ Weaver Version
、register classloader
或 using configuration .../aop.xml
等字符串。如果您正确地将 aspectjweaver.jar
和 META-INF/aop.xml
添加到项目中,您应该会看到类似的内容,即使由于某种原因该方面没有被触发。
- 确保
META-INF/aop.xml
被 Java 进程找到。它由 AspectJ 通过 Classloader.getResource()
定位。因此,无论您将它放在什么位置或 JAR 中,请确保该位置在类路径中。实验性地,您可以将本地目录添加到类路径,然后查看 JVM 是否在那里找到 XML 文件。然后,如果找到这种方法,您可以开始改进您的方法。
- 顺便说一句,我看到
<include within="com.al6.*"/>
只能直接匹配包 com.al6
中的 类。如果你想包含子包,你需要使用 ..
语法,即 <include within="com.al6..*"/>
.
- 此外,您还链接到最新 Spring 手册中有关本机 AspectJ + LTW 配置的操作方法。您应该使用 Spring 4.0.6 documentation, because you use that legacy version. I already sent you a link in my comment under your previous question.
请先尝试通过添加 -javaagent:/path/to/aspectjweaver.jar
获取我在第一个要点中提到的字符串,然后再尝试其他任何操作。只有这样,您可能需要优化或微调:
对于JBoss有一个特殊的JBossLoadTimeWeaver
。它应该是自动检测的,但您也可以手动指定它,请参阅 this table of default weavers。
找不到为什么加载时编织不起作用。
所以,我工作中有人问我为什么要进行加载时织入,为什么不直接进行“编译时织入”。
我只是将其添加到我的 pom.xml 中:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<complianceLevel>1.6</complianceLevel>
<source>1.6</source>
<target>1.6</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8 </encoding>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
我删除了 javaagent 的东西。
Build,运行,tada,它正在运行。
我不明白为什么几乎没有人谈论这种方法,它不需要在启动参数中添加任何东西,任何复杂的东西,而且工作起来容易得多。
这有什么不方便的吗?
事实上,我想知道它是不是更好,因为它在编译时编织 类,所以它会使用更少的系统资源?
我有一个旧的 Java6 应用程序,我正在尝试添加一些自动和全局日志来跟踪每个方法中的每个调用。 它 运行s 在 JBoss 4.2.3.
我有我的个人资料 class :
package com.al6.borneIntranet.business.log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;
import org.springframework.core.annotation.Order;
@Aspect
public class ProfilingAspect {
@Around("methodsToBeProfiled()")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
StopWatch sw = new StopWatch(getClass().getSimpleName());
try {
sw.start(pjp.getSignature().getName());
return pjp.proceed();
} finally {
sw.stop();
System.out.println(sw.prettyPrint());
}
}
@Pointcut("execution(public * com.al6.borneIntranet..*.*(..))")
public void methodsToBeProfiled(){}
}
我创建了一个 META-INF/aop.xml 文件:
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in our application-specific packages -->
<include within="com.al6.*"/>
</weaver>
<aspects>
<!-- weave in just this aspect -->
<aspect name="com.al6.borneIntranet.business.log.ProfilingAspect"/>
</aspects>
</aspectj>
我在我的 bean 定义中添加了这一行 xml :
<context:load-time-weaver/>
我有这个依赖关系:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
它几乎可以工作,但我在使用该应用程序时在启动时出现此错误:
2021-04-29 18:41:46,960 ERROR [STDERR] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.jboss.mx.loading.UnifiedClassLoader3] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
我从 Maven 存储库下载 spring-instrument-4.0.6.RELEASE.jar 文件,然后在 运行 启动脚本中添加 javaagent 部分:
/opt/jdk/bin/java -Dprogram.name=run.sh -javaagent:/opt/jboss/lib/org.springframework.instrument.jar -server -Xms2048m -Xmx2048m -XX:MaxPermSize=256M ...
但是还是报错,像什么都没做一样
有没有办法在启动时轻松不添加此选项? 为什么即使我添加了它也没有被使用?
编辑:
我尝试添加 adspectj 启动代理,但也没有用,同样的错误,应用程序似乎未检测到该选项:
/bin/sh /opt/jboss/bin/run.sh -c commandes -b 0.0.0.0 -Djboss.partition.name=jboss-commande-preprod1-partition
admin 22263 47.6 76.7 4911056 4023536 pts/0 Sl 16:03 2:14 /opt/jdk/bin/java -Dprogram.name=run.sh -javaagent:/opt/jboss/lib/aspectjweaver-1.8.9.jar -javaagent:/opt/jboss/lib/org.springframework.instrument.jar -server -Xms3500m -Xmx
3500m -XX:MaxPermSize=512M -Dfile.encoding=UTF-8 -Djava.awt.headless=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dc
om.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -XX:+UseG1GC -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -Djava.net.prefer
IPv4Stack=true -Djava.endorsed.dirs=/opt/jboss/lib/endorsed -classpath /opt/jboss/bin/run.jar:/opt/jdk/lib/tools.jar org.jboss.Main -c commandes -b 0.0.0.0 -Djboss.partition.name=jboss-commande-preprod1-partition
编辑 2:
尝试一些事情:
使用 Jboss timeweaver :
创建名为 'loadTimeWeaver' 的 bean 时出错:bean 实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 bean class [org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver]:构造函数抛出异常;嵌套异常是 java.lang.IllegalStateException: 无法初始化 JBoss LoadTimeWeaver 因为 JBoss 6 API classes 不可用
当然,我在 Jboss 4.3.2
- 在 aop.xml 中添加“-verbose -showWeaveInfo -debug”:
文件被检测到,因为我在启动时有这些行:
2021-05-03 15:11:42,267 ERROR [STDERR] [UnifiedClassLoader3@341a736] info AspectJ Weaver Version 1.8.9 built on Monday Mar 14, 2016 at 21:18:16 GMT
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register classloader org.jboss.mx.loading.UnifiedClassLoader3@341a736
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info using configuration file:/opt/jboss-4.2.3.GA/server/weldom_commandes/tmp/deploy/tmp6458410370486804467BorneIntranetServeurMetier.ear-contents/BorneIntranetServeurMetier.jar!/META-INF/aop.xml
2021-05-03 15:11:43,253 ERROR [STDERR] [UnifiedClassLoader3@341a736] info using configuration file:/opt/jboss-4.2.3.GA/server/weldom_commandes/tmp/deploy/tmp6458410370486804467BorneIntranetServeurMetier.ear-contents/spring-aspects-4.0.6.RELEASE.jar!/META-INF/aop.xml
2021-05-03 15:11:43,259 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect com.al6.borneIntranet.business.log.ProfilingAspect
2021-05-03 15:11:43,474 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
2021-05-03 15:11:43,520 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
2021-05-03 15:11:43,536 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
2021-05-03 15:11:43,544 ERROR [STDERR] [UnifiedClassLoader3@341a736] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
2021-05-03 15:11:43,559 ERROR [STDERR] [UnifiedClassLoader3@341a736] debug not weaving 'com.al6.borneIntranet.business.ServiceArchiveEntryPointBean'
...
当我输入时:
<context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
我的错误略有不同,但结果相同:
2021-05-03 15:15:03,475 ERROR [STDERR] java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
2021-05-03 15:15:03,476 ERROR [STDERR] at org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver.addTransformer(InstrumentationLoadTimeWeaver.java:88)
但我已经添加了它:
-javaagent:/opt/jboss/lib/org.springframework.instrument.jar
ls -lrt /opt/jboss/lib :
-rwxrwxrwx 1 admin users 7244 2021-04-30 16:03 /opt/jboss/lib/org.springframework.instrument.jar*
我不是 Spring 用户,但是在这里回答 AspectJ LTW 问题时,我经常注意到 Spring 文档之间存在一定的差异,提到需要 Spring Instrument Java 仅代理,在实际情况下可以像这样配置 Spring,但这很棘手。到目前为止最简单的方法是将 AspectJ Weaver 代理也添加到命令行,即使用类似的东西(当然是在一行上)
# AspectJ LTW
-javaagent:/path/to/aspectjweaver.jar
# Spring Instrument
-javaagent:/path/to/org.springframework.instrument.jar
也许 AspectJ Weaver 已经足够了,这取决于您的用例。
更新 在 OP 更新他的问题后:
- 您是否在您的应用程序服务器日志中看到正在加载 AspectJ weaver 的任何迹象?扫描
AspectJ Weaver Version
、register classloader
或using configuration .../aop.xml
等字符串。如果您正确地将aspectjweaver.jar
和META-INF/aop.xml
添加到项目中,您应该会看到类似的内容,即使由于某种原因该方面没有被触发。 - 确保
META-INF/aop.xml
被 Java 进程找到。它由 AspectJ 通过Classloader.getResource()
定位。因此,无论您将它放在什么位置或 JAR 中,请确保该位置在类路径中。实验性地,您可以将本地目录添加到类路径,然后查看 JVM 是否在那里找到 XML 文件。然后,如果找到这种方法,您可以开始改进您的方法。 - 顺便说一句,我看到
<include within="com.al6.*"/>
只能直接匹配包com.al6
中的 类。如果你想包含子包,你需要使用..
语法,即<include within="com.al6..*"/>
. - 此外,您还链接到最新 Spring 手册中有关本机 AspectJ + LTW 配置的操作方法。您应该使用 Spring 4.0.6 documentation, because you use that legacy version. I already sent you a link in my comment under your previous question.
请先尝试通过添加 -javaagent:/path/to/aspectjweaver.jar
获取我在第一个要点中提到的字符串,然后再尝试其他任何操作。只有这样,您可能需要优化或微调:
对于JBoss有一个特殊的JBossLoadTimeWeaver
。它应该是自动检测的,但您也可以手动指定它,请参阅 this table of default weavers。
找不到为什么加载时编织不起作用。
所以,我工作中有人问我为什么要进行加载时织入,为什么不直接进行“编译时织入”。
我只是将其添加到我的 pom.xml 中:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<complianceLevel>1.6</complianceLevel>
<source>1.6</source>
<target>1.6</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8 </encoding>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
我删除了 javaagent 的东西。
Build,运行,tada,它正在运行。
我不明白为什么几乎没有人谈论这种方法,它不需要在启动参数中添加任何东西,任何复杂的东西,而且工作起来容易得多。
这有什么不方便的吗? 事实上,我想知道它是不是更好,因为它在编译时编织 类,所以它会使用更少的系统资源?