检查是否加载了 aspectjweaver(或任何 javaagent)
Check if aspectjweaver (or any javaagent) is loaded
是否有(首选便携式)方法来检查是否
JVM 已用特定的 -javaagent
?
声明
我特别想知道 aspectj 加载时间编织器是否已加载。 (我试图在启动不正确的情况下提供有用的错误消息)。
以下代码显示
- 一种确定任何
-javaagent:...
JVM 参数的方法,
- 一种检查 AspectJ 编织代理入口点的方法 class(aspectjweaver.jar 的清单条目
Premain-Class:
中提到的那个) 已加载。
前者只是证明参数是在命令行给出的,并不是真正找到并启动了代理。
后者只是证明编织器在class路径上可用,并不是说它真的是作为代理启动的。两者的结合应该让您非常有信心代理实际上是活跃的。
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;
}
更新二:
在与 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;
}
现在两种主要错误类型
- 编织代理在 class 路径上可用,但检测尚未启动,因为 aspectjweaver.jar 未作为 Java 启动经纪人,
- 代理 aspectjweaver.jar 根本不在 class 路径上,因此 class
org.aspectj.weaver.loadtime.Agent
不可用
通过返回 false
after 警告消息(在这个简单的示例中只是清楚说明错误的异常)已打印在控制台上,从而得到妥善处理。
这两种情况可能的控制台输出是:
java.lang.UnsupportedOperationException: Java 5 was not started with preMain -javaagent for AspectJ
java.lang.NoClassDefFoundError: org/aspectj/weaver/loadtime/Agent
我发现了以下作品(针对 1.8.4 进行了测试),尽管 它依赖于未记录的 aspectjweaver 功能,因此可能无法跨版本工作。
public static boolean isAspectJAgentLoaded() {
try {
org.aspectj.weaver.loadtime.Agent.getInstrumentation();
return true;
} catch (UnsupportedOperationException e) {
return false;
}
}
解释:当aspectj作为代理加载时,org.aspectj.weaver.loadtime.Agent.premain(...)
静态方法被JVM调用。这有一个我们可以测试的副作用。调用 getInstrumentation
要么抛出 UnsupportedOperationException
(如果它没有初始化为代理),要么抛出 returns 成功。
是否有(首选便携式)方法来检查是否
JVM 已用特定的 -javaagent
?
我特别想知道 aspectj 加载时间编织器是否已加载。 (我试图在启动不正确的情况下提供有用的错误消息)。
以下代码显示
- 一种确定任何
-javaagent:...
JVM 参数的方法, - 一种检查 AspectJ 编织代理入口点的方法 class(aspectjweaver.jar 的清单条目
Premain-Class:
中提到的那个) 已加载。
前者只是证明参数是在命令行给出的,并不是真正找到并启动了代理。
后者只是证明编织器在class路径上可用,并不是说它真的是作为代理启动的。两者的结合应该让您非常有信心代理实际上是活跃的。
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;
}
更新二:
在与 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;
}
现在两种主要错误类型
- 编织代理在 class 路径上可用,但检测尚未启动,因为 aspectjweaver.jar 未作为 Java 启动经纪人,
- 代理 aspectjweaver.jar 根本不在 class 路径上,因此 class
org.aspectj.weaver.loadtime.Agent
不可用
通过返回 false
after 警告消息(在这个简单的示例中只是清楚说明错误的异常)已打印在控制台上,从而得到妥善处理。
这两种情况可能的控制台输出是:
java.lang.UnsupportedOperationException: Java 5 was not started with preMain -javaagent for AspectJ
java.lang.NoClassDefFoundError: org/aspectj/weaver/loadtime/Agent
我发现了以下作品(针对 1.8.4 进行了测试),尽管 它依赖于未记录的 aspectjweaver 功能,因此可能无法跨版本工作。
public static boolean isAspectJAgentLoaded() {
try {
org.aspectj.weaver.loadtime.Agent.getInstrumentation();
return true;
} catch (UnsupportedOperationException e) {
return false;
}
}
解释:当aspectj作为代理加载时,org.aspectj.weaver.loadtime.Agent.premain(...)
静态方法被JVM调用。这有一个我们可以测试的副作用。调用 getInstrumentation
要么抛出 UnsupportedOperationException
(如果它没有初始化为代理),要么抛出 returns 成功。