在“fat jar”中指定Java代理?

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

是否可以在jar文件内指定位置来使用-javaagent开关?

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

2个回答

2
根据 java.lang.instrumentation 文档,这可能是可行的。
如果实现允许,jetty-alpn-agent.jar 必须是系统类路径的一部分。因此,您必须像其他应用程序库一样将其包含在 my.jar 中。

Starting Agents After VM Startup

An implementation may provide a mechanism to start agents sometime after the the VM has started. The details as to how this is initiated are implementation specific but typically the application has already started and its main method has already been invoked. In cases where an implementation supports the starting of agents after the VM has started the following applies:

The manifest of the agent JAR must contain the attribute Agent-Class. The value of this attribute is the name of the agent class.

The agent class must implement a public static agentmain method.

The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path.

The agent JAR is appended to the system class path. This is the class loader that typically loads the class containing the application main method. The agent class is loaded and the JVM attempts to invoke the agentmain method. The JVM first attempts to invoke the following method on the agent class:

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

If the agent class does not implement this method then the JVM will attempt to invoke:

public static void agentmain(String agentArgs);

The agent class may also have an premain method for use when the agent is started using a command-line option. When the agent is started after VM startup the premain method is not invoked.

The agent is passed its agent options via the agentArgs parameter. The agent options are passed as a single string, any additional parsing should be performed by the agent itself.

The agentmain method should do any necessary initialization required to start the agent. When startup is complete the method should return. If the agent cannot be started (for example, because the agent class cannot be loaded, or because the agent class does not have a conformant agentmain method), the JVM will not abort. If the agentmain method throws an uncaught exception it will be ignored.

PS:我从未尝试过这个。如果有效,请告诉我。


谢谢,这可能是更“简单”的代理jar的选项,但是这个特定的jar内部有jar,并且我还需要创建一个包装类来实现“agentmain()”方法,当它尝试加载时会导致类路径问题。 我想我只能咬紧牙关将其添加到“agents”目录并将其添加到启动脚本中。我们最终要迁移到的平台将在部署时自动检测此代理jar,因此我可以将其作为临时解决方案接受。 - Niklas Herder
运行时附加并不能保证类在附加时还未被加载。已经加载的类只能通过提供不同的方法实现来进行更改,而不能允许不同的形状。 - Rafael Winterhalter

1

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接