如何使用Boot Gradle插件在Spring Boot应用程序中嵌入Java Agent

5

我正在使用Java代理程序来管理我的Spring Boot应用程序,并且目前正在运行它通过

java -javaagent:agent.jar -jar app.jar

我的项目是一个gradle项目,我想将agent.jar嵌入到app.jar中,以便可以将其作为应用程序运行。

java -javaagent:app.jar -jar app.jar

这可以通过boot maven插件完成,如此处所述-https://jeroendruwe.be/spring-boot-and-new-relic/,但是没有适用于boot gradle插件的替代方案。我找到的最接近的是这个-https://jdpgrailsdev.github.io/blog/2014/04/08/spring_boot_gradle_newrelic.html,但它不能像预期的那样嵌入jar包。是否有办法通过gradle完成呢?

那是为了什么目的?在微服务中嵌入基础设施/工具库等绝对不是最佳实践,而你的Spring Boot应用程序很可能是属于微服务类型的。 - yuranos
目的是让Spring Boot应用程序在Cloud Foundry上运行,而我们还没有适用于该代理的任何服务。因此,我希望将代理jar嵌入到启动jar中,这样我们就可以将其推送到CF并完成所有操作,而无需进行其他配置更改。 - Anindya Chatterjee
3个回答

0

你试过了吗?

java -Xbootclasspath=('your path'/app.jar or 'your path to libs'/agent.jar) -javaagent:'your path'/app.jar -jar 'your path'/app.jar

?

另一种方法:使用jar作为依赖项,并将(或创建另一个)你的premain类移动到Spring Boot应用程序jar中。

这将会把代理类放置在BOOT-INF/classes文件夹中,该文件夹位于启动jar包内,而且无法通过-javaagent参数进行访问。 - Anindya Chatterjee
有趣的是,-Xbootclasspath(https://docs.oracle.com/cd/E15289_01/doc.40/e15062/optionx.htm#i1018570)不是编译选项,而是用于运行jar文件的选项,所以我不明白它如何能够将jar文件复制到任何地方?为什么不只是将代理jar文件复制到根文件夹中?https://dev59.com/VF7Va4cB1Zd3GeqPJ3Se。 - egorlitvinenko
我并没有提到bootclasspath。我的意思是,当我使用gradle build创建一个spring boot jar时,它会将premain类放在BOOT-INF/classes文件夹中,并将代理jar放在BOOT-INF/libs文件夹中。你的命令行参数无法与这个boot jar布局配合使用。 - Anindya Chatterjee

0

可以将本地目录中的JAR包作为依赖项添加。'libs'是您项目内部的一个目录。

依赖关系 { 编译 文件树(目录:'libs',包括:'*.jar') }


这将把它放在BOOT-INF/lib目录下,这样在引导期间不会加载代理jar。但是我希望代理jar的类位于引导jar的最顶层目录中,以便MANIFEST.MF中的Pre-Main指令可以找到该类。 - Anindya Chatterjee
@AnindyaChatterjee,你能找到解决方案吗? - sutanu dalui

0

Gradle Jar:

jar {
manifest{
    attributes "Agent-Class" : "com.......agent.AgentTest"
    //attributes "Premain-Class" : "com.......agent.AgentTest"
        }
    }

虽然我习惯这样做:

    public static void main(String[] args) throws Exception {
    String pid = "6236";
    String agentPath = "...";
    VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(pid);
    virtualmachine.loadAgent("/home/aaa/Code/agent-1.0-SNAPSHOT.jar");
    virtualMachine.detach();
}

当我在cf环境中运行应用程序时,如何获取pid?我的唯一目标是以可移植的方式在不同的cf环境中运行此应用程序。 - Anindya Chatterjee
@AnindyaChatterjee 对不起,我不确定这个。也许你可以尝试使用 build.gradle 应用插件:'maven',详情可咨询 https://docs.gradle.org/current/userguide/maven_plugin.html。 - saaav

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