【问题标题】:Attach java agent from all-in-one-jar从 all-in-one-jar 附加 java 代理
【发布时间】:2015-04-23 19:01:19
【问题描述】:

我只是想尝试一下 javassist,然后开始编辑库的方法体。要连接到库,我使用位于 '%JAVA_HOME%..\lib\' 中的 tools.jar 附加了一个代理。

但我不喜欢我使用的每台电脑都只为 tools.jar 安装 jdk 的想法

难道没有其他方法可以将 jar 的输入提取到我的最终 jar 中吗?
我用 javassist 这样做了,它似乎工作正常(IntelliJ 这样做了。它有一个很好的功能http://puu.sh/hoiCo/bf19853b12.png
但是使用 tools.jar 会导致程序抛出异常

异常http://puu.sh/hoiGd/844567bca2.png的截图

public static void main(String[] args){
    if(args.length < 1){
        log("No ProcessID set");
        return;
    }
    String pid = args[0];
    VirtualMachine vm = null;
    try{
        vm = VirtualMachine.attach(pid);
        String filePath = AgentMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        filePath = URLDecoder.decode(filePath, "UTF-8");
        if(filePath.startsWith("/")){
            filePath = filePath.substring(1);
        }
        log("Loading Agent... [" + filePath + "]");
        vm.loadAgent(filePath);
    }catch(Exception ex){
        log("VM connection error [" + pid + "]");
        ex.printStackTrace();
    }finally{
        try{
            if(vm != null) vm.detach();
        }catch(Exception ex){}
    }
}

这是我用于注入代理的代码。

如果有人可以提供帮助,那就太好了。
我希望你明白:)

【问题讨论】:

    标签: java intellij-idea javassist tools.jar


    【解决方案1】:

    这个项目可能会对你有所帮助:orbit/agent-loader

    public class HelloAgent
    {
        public static void agentmain(String agentArgs, Instrumentation inst)
        {
            System.out.println(agentArgs);
            System.out.println("Hi from the agent!");
            System.out.println("I've got instrumentation!: " + inst);
        }
    }
    
    public static void main(String[] args)
    {
        AgentLoader.loadAgentClass(HelloAgent.class.getName(), "Hello!");
    }
    

    它将 VirtualMachine 类捆绑在其中,因此您不需要工具 jar 在运行时附加代理。

    maven

    <dependency>
        <groupId>com.ea.orbit</groupId>
        <artifactId>orbit-agent-loader</artifactId>
        <version>0.5.2</version>
    </dependency>
    

    应该可以将它与您的应用程序捆绑在一个 jar 中。


    从您的 cmets 不清楚您是否知道这一点,但您也可以使用 VM 选项运行您的程序: -javaagent:your-agent.jar

    附带说明:在 Intellij 中,您可以将 java 程序和单元测试的默认启动器设置为默认具有 -javaagent:something.jar。有趣的是,jar 不需要有实际的代理类,它只需要正确的manifest entries。 (前提是您的代理类位于您正在运行的项目/模块的类路径中)。

    【讨论】:

    • 看起来很酷,但实际上我已经找到了解决方案。我希望我的程序像 dll 一样“可注入”,所以 -javaagent vm 选项不是我的解决方案。但感谢另一个解决方案:)
    猜你喜欢
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2021-03-31
    • 1970-01-01
    • 2017-10-25
    • 2013-07-11
    • 2010-09-23
    相关资源
    最近更新 更多