简体   繁体   English

在'fat jar'中指定java代理?

[英]Specify java agent inside 'fat jar'?

I am using the jetty-alpn-agent to add ALPN support to my project, but all I can find is instructions on how to run it from the .m2 folder, which makes me need to deploy two jar:s instead of just my one uber-jar, making it less portable. 我正在使用jetty-alpn-agent为我的项目添加ALPN支持,但我能找到的是如何从.m2文件夹运行它的说明,这使得我需要部署两个jar:s而不仅仅是我的一个超级罐,使其便携性降低。

Is is possible to specify a location inside the jar to the -javaagent switch? 是否可以在jar中指定-javaagent开关的位置?

I'm looking for something like java -javaagent:my.jar!/javaagents/jetty-alpn-agent-2.0.0.jar -jar myjar.jar , but that doesn't seem to work. 我正在寻找像java -javaagent:my.jar!/javaagents/jetty-alpn-agent-2.0.0.jar -jar myjar.jar ,但这似乎不起作用。

It might be possible according to the java.lang.instrumentation documentation. 根据java.lang.instrumentation文档,它可能是可能的。

If the implementation allows it the jetty-alpn-agent.jar must be part of the system classpath. 如果实现允许,则jetty-alpn-agent.jar必须是系统类路径的一部分。 So you must include it in your my.jar like any other application library. 所以你必须像任何其他应用程序库一样将它包含在my.jar

Starting Agents After VM Startup VM启动后启动代理

An implementation may provide a mechanism to start agents sometime after the the VM has started. 实现可以提供在VM启动之后的某个时间启动代理的机制。 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: 如果实现支持在VM启动后启动代理,则以下情况适用:

The manifest of the agent JAR must contain the attribute Agent-Class. 代理JAR的清单必须包含属性Agent-Class。 The value of this attribute is the name of the agent class. 此属性的值是代理类的名称。

The agent class must implement a public static agentmain method. 代理类必须实现公共静态agentmain方法。

The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path. 系统类加载器(ClassLoader.getSystemClassLoader)必须支持将代理JAR文件添加到系统类路径的机制。

The agent JAR is appended to the system class path. 代理JAR附加到系统类路径。 This is the class loader that typically loads the class containing the application main method . 这是通常加载包含应用程序main方法的类的类加载器 The agent class is loaded and the JVM attempts to invoke the agentmain method. 加载代理程序类,JVM尝试调用agentmain方法。 The JVM first attempts to invoke the following method on the agent class: JVM首先尝试在代理类上调用以下方法:

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

If the agent class does not implement this method then the JVM will attempt to invoke: 如果代理类未实现此方法,则JVM将尝试调用:

 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. 当使用命令行选项启动代理时,代理类还可以具有premain方法。 When the agent is started after VM startup the premain method is not invoked. 在VM启动后启动代理程序时,不会调用premain方法。

The agent is passed its agent options via the agentArgs parameter. 代理程序通过agentArgs参数传递其代理程序选项。 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. agentmain方法应该执行启动代理所需的任何必要的初始化。 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. 如果无法启动代理(例如,因为无法加载代理类,或者因为代理类没有符合的agentmain方法),JVM将不会中止。 If the agentmain method throws an uncaught exception it will be ignored. 如果agentmain方法抛出未捕获的异常,则将忽略它。

PS: I have never tried this. PS:我从未尝试过这个。 Please let me know if it works or not. 如果有效,请告诉我。

You can emulate the previous agent by writing the premain class into your fat jar's manifest. 您可以通过将premain类写入fat jar的清单来模拟前一个代理。 Then, simply add your fat jar both via the javaagent and and as the jar argument. 然后,只需通过javaagentjar参数添加你的胖罐。

It is not possible to avoid this as the instrumentation API is quite powerful and allows to avoid a security manager what would offer an entry point for an attack. 由于检测API非常强大并且允许避免安全管理器提供攻击的入口点,因此无法避免这种情况。 You can however self-attach on a JDK or a Java 9 VM. 但是,您可以在JDK或Java 9 VM上进行自我连接。 The byte-buddy-agent library offers a ready-made dependency for this. byte-buddy-agent库为此提供了现成的依赖项。 This way, you can invoke your premain method manually after getting hold of an instrumentation instance. 这样,您可以在获取检测实例后手动调用premain方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM