如何在代码中动态添加Java代理JAR后卸载它们?Java工具

如何在代码中动态添加Java代理JAR后卸载它们?Java工具,java,instrumentation,agent,javaagents,Java,Instrumentation,Agent,Javaagents,我创建了一个java代理jar文件(它在命令行上工作得非常好)。 接下来,我想将此代理附加到j2ee服务器中正在运行的JVM。 所以我使用了代码: public static void loadAgent() { System.out.println("dynamically loading javaagent"); String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName(); i

我创建了一个java代理jar文件(它在命令行上工作得非常好)。 接下来,我想将此代理附加到j2ee服务器中正在运行的JVM。 所以我使用了代码:

public static void loadAgent() {   

    System.out.println("dynamically loading javaagent");
    String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
    int p = nameOfRunningVM.indexOf('@');
    String pid = nameOfRunningVM.substring(0, p);

    try {
        VirtualMachine vm = VirtualMachine.attach(pid);
        String jarFilePath = vm.getSystemProperties().getProperty("java.home")+File.separator+"lib"+File.separator+"test-agent-7.jar";            
        vm.loadAgent(jarFilePath, "");
        vm.detach();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
编辑:这是现在的工作,我能够看到变压器被调用。 我还可以删除变压器,并能够调试变压器

我的问题是:

  • 完成后如何卸载此java代理jar?
  • 是关闭/重新启动JVM的唯一方法吗
  • 如果将jar留在内存中,会有任何影响吗

    • 嗯,有几件事需要考虑:

      如果加载代理,则加载类。只要相关的类加载器在JavaVM的内存中,关联的类就会保持加载状态。我认为你不能轻易地阻止/规避那件事。但这应该只是一个小的内存开销,您通过加载代理而产生

      一些研究表明,代理将由SystemClassLoader加载,因此卸载这些类是不可能的

      VM启动后启动代理

      一个实现可以提供一种机制来启动代理 在虚拟机启动之后。有关如何启动的详细信息 是特定于实现的,但通常应用程序已经 已启动,并且已调用其主方法。如果 实现支持在VM启动后启动代理 以下情况适用: 代理JAR的清单必须包含属性agent类。此属性的值是代理的名称 班级。 代理类必须实现公共静态agentmain方法。 系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR文件添加到系统类路径的机制。

      然而,你能影响的是代理人的所作所为

      你想关闭那个代理吗?提供关闭方法

      如果您想从外部停止代理,该代理可以提供一个JMXBean来关闭代理

      然后,该方法可以从检测接口中删除转换器,或者停止代理在Java VM中执行的任何其他操作(释放所持有的引用/资源,以便对对象进行垃圾收集,诸如此类)


      如果没有更具体地说明您想要实现的目标,就很难给出更合适的答案。

      您的问题@Tal解决了吗?不幸的是,没有。。。代理jar保持加载状态。。