是否有(pref portable)方式检查是否
已经使用特定-javaagent
?
特别是我有兴趣知道是否加载了aspectj加载时间织入器。 (我正在尝试在启动不正确的情况下提供有用的错误消息)。
答案 0 :(得分:10)
以下代码显示
-javaagent:...
JVM参数的方法,Premain-Class:
中提到的类)的方法。前者只是证明了这个参数是在命令行中给出的,而不是实际找到并启动了代理。
后者只是证明了weaver在类路径上是可用的,而不是它实际上是作为代理启动的。两者的结合应该让你非常相信代理实际上是活跃的。
package de.scrum_master.app;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.List;
public class Application {
public static void main(String[] args) {
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
for (String argument : arguments) {
if (argument.startsWith("-javaagent:"))
System.out.println(argument);
}
try {
Class.forName("org.aspectj.weaver.loadtime.Agent");
} catch (ClassNotFoundException e) {
System.err.println("WARNING: AspectJ weaving agent not loaded");
}
}
}
您也可能会发现问题Starting a Java agent after program start,其中一些答案会有所帮助。
<强>更新强>
好的,这是我自己的解决方案和你的解决方案的组合,但是即使编织器不可用也能正常工作,这很重要,因为这是你想要首先检查的内容:
public static boolean isAspectJAgentLoaded() {
try {
Class<?> agentClass = Class.forName("org.aspectj.weaver.loadtime.Agent");
Method method = agentClass.getMethod("getInstrumentation");
method.invoke(null);
} catch (Exception e) {
//System.out.println(e);
return false;
}
return true;
}
更新2:
在与OP bacar 进行一些讨论之后,我决定提供一种不使用反射但却捕获NoClassDefError
的解决方案:
public static boolean isAspectJAgentLoaded() {
try {
org.aspectj.weaver.loadtime.Agent.getInstrumentation();
} catch (NoClassDefFoundError | UnsupportedOperationException e) {
System.out.println(e);
return false;
}
return true;
}
现在两种主要错误类型
org.aspectj.weaver.loadtime.Agent
类不可用false
,然后在控制台上打印出<{1>} (在这个简单的例子中只是明确说明错误的例外情况)。
这两种情况的可能的控制台输出是:
java.lang.UnsupportedOperationException: Java 5 was not started with preMain -javaagent for AspectJ
java.lang.NoClassDefFoundError: org/aspectj/weaver/loadtime/Agent
答案 1 :(得分:0)
我发现以下作品(针对1.8.4进行了测试),虽然它依赖于未记录的aspectjweaver功能,因此可能无法跨版本工作。
public static boolean isAspectJAgentLoaded() {
try {
org.aspectj.weaver.loadtime.Agent.getInstrumentation();
return true;
} catch (UnsupportedOperationException e) {
return false;
}
}
说明:当aspectj作为代理加载时,JVM会调用org.aspectj.weaver.loadtime.Agent.premain(...)
静态方法。这有一个我们可以测试的副作用。调用getInstrumentation
会抛出UnsupportedOperationException
(如果它没有初始化为代理),如果是,则返回成功。