7

我正在使用jetty-alpn-agent为我的项目添加 ALPN 支持,但我能找到的只是有关如何从.m2文件夹中运行它的说明,这使我需要部署两个 jar:s 而不仅仅是我的一个 uber-jar,使其更少便携的。

是否可以为 -javaagent 开关指定 jar 内的位置?

我正在寻找类似的东西java -javaagent:my.jar!/javaagents/jetty-alpn-agent-2.0.0.jar -jar myjar.jar,但这似乎不起作用。

4

2 回答 2

1

根据java.lang.instrumentation文档,这可能是可能的。

如果实现允许它jetty-alpn-agent.jar必须是系统类路径的一部分。因此,您必须my.jar像任何其他应用程序库一样将其包含在您的应用程序库中。

虚拟机启动后启动代理

实现可以提供一种机制来在 VM 启动后的某个时间启动代理。关于如何启动的细节是特定于实现的,但通常应用程序已经启动并且它的 main 方法已经被调用。如果实现支持在 VM 启动后启动代理,则适用以下情况:

代理 JAR 的清单必须包含属性 Agent-Class。该属性的值是代理类的名称。

代理类必须实现公共静态 agentmain 方法。

系统类加载器 (ClassLoader.getSystemClassLoader) 必须支持将代理 JAR 文件添加到系统类路径的机制。

代理 JAR 附加到系统类路径这是通常加载包含应用程序主方法的类的类加载器。代理类被加载,JVM 尝试调用 agentmain 方法。JVM 首先尝试在代理类上调用以下方法:

public static void agentmain(String agentArgs, Instrumentation inst);

如果代理类未实现此方法,则 JVM 将尝试调用:

public static void agentmain(String agentArgs);

当使用命令行选项启动代理时,代理类也可能有一个 premain 方法。在 VM 启动后启动代理时,不会调用 premain 方法。

代理通过 agentArgs 参数传递其代理选项。代理选项作为单个字符串传递,任何额外的解析都应该由代理自己执行。

agentmain 方法应该执行启动代理所需的任何必要初始化。启动完成后,该方法应返回。如果无法启动代理(例如,因为无法加载代理类,或者因为代理类没有符合的 agentmain 方法),则 JVM 不会中止。如果 agentmain 方法抛出未捕获的异常,它将被忽略。

PS:我从来没有试过这个。请让我知道它是否有效。

于 2016-08-19T07:58:18.923 回答
0

您可以通过将 premain 类写入 fat jar 的清单来模拟以前的代理。然后,只需通过javaagentjar参数添加您的 fat jar。

无法避免这种情况,因为检测 API 非常强大,并且允许避免安全管理器提供攻击的入口点。但是,您可以在 JDK 或 Java 9 VM 上进行自连接。byte-buddy-agent库为此提供了现成的依赖项。这样,您可以在获取检测实例后手动调用您的 premain 方法。

于 2016-08-20T08:52:19.357 回答