检查是否加载了aspectjweaver(或任何javaagent)

时间:2015-01-21 19:34:04

标签: java aspectj javaagents

是否有(pref portable)方式检查是否 已经使用特定-javaagent

声明了JVM

特别是我有兴趣知道是否加载了aspectj加载时间织入器。 (我正在尝试在启动不正确的情况下提供有用的错误消息)。

2 个答案:

答案 0 :(得分:10)

以下代码显示

  • 一种确定任何-javaagent:... JVM参数的方法,
  • 检查是否加载了AspectJ编织代理入口点类( aspectjweaver.jar 的清单条目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;
}

现在两种主要错误类型

  • 编织代理在类路径上可用,但尚未启动检测,因为 aspectjweaver.jar 未作为Java代理启动,
  • agent aspectjweaver.jar 根本不在类路径上,因此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(如果它没有初始化为代理),如果是,则返回成功。