5

I am using a javaagent for my spring boot app and currently I am running it via

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

My project is a gradle project and I want to embed the agent.jar inside the app.jar so that I can run it as

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

It can be done via boot maven plugin as mentioned here - https://jeroendruwe.be/spring-boot-and-new-relic/ but there is no alternative for boot gradle plugin. The closest I find is this - https://jdpgrailsdev.github.io/blog/2014/04/08/spring_boot_gradle_newrelic.html, but it does not embed the jar as intended.

Is there anyway it can be done via gradle?

Anindya Chatterjee
  • 5,824
  • 13
  • 58
  • 82
  • What's the purpose of that? It's definitely not a best practice to embed infrastructural/util/etc libs inside a microservice, which your spring boot application probably is. – yuranos Dec 26 '17 at 12:31
  • The purpose is that the spring boot app runs in cloud foundry and we don't have any service for that agent yet. So I want the agent jar to be embedded inside the boot jar, so that we can push it to cf and be done with it without any other config changes. – Anindya Chatterjee Dec 26 '17 at 16:46

3 Answers3

0

Can be add as dependency jar from local directory. 'libs' is directory inside your project.

dependencies { compile fileTree(dir: 'libs', include: '*.jar') }

  • This would put it under BOOT-INF/lib directory which will not load the agent jar during bootstrap. But I want the classes of the agent jar in the topmost directory of the boot jar so Pre-Main instruction in the MANIFEST.MF could find the class. – Anindya Chatterjee Dec 26 '17 at 11:15
  • @AnindyaChatterjee were you able to figure out a solution? – sutanu dalui Feb 19 '22 at 13:43
0

gradle jar :

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

Althought, I am using to do like this :

    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();
}
saaav
  • 34
  • 4
  • How do I get the pid when I run the app in cf environment? My only objective is to run this in a portable way in different cf environment. – Anindya Chatterjee Dec 27 '17 at 07:40
  • @AnindyaChatterjee Sorry, I'm not sure about this.Maybe you can try it: build.gradle apply plugin: 'maven' and the detail could be concult https://docs.gradle.org/current/userguide/maven_plugin.html – saaav Dec 27 '17 at 08:13
0

Did you try

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

?

Another approach: use jar as dependency and move (or create another one) your premain class in Spring Boot application jar.

egorlitvinenko
  • 2,736
  • 2
  • 16
  • 36
  • This would place the agent class in BOOT-INF/classes folder inside the boot jar which again is not accessible via -javaagent argument. – Anindya Chatterjee Dec 27 '17 at 07:38
  • Interesting, -Xbootclasspath (https://docs.oracle.com/cd/E15289_01/doc.40/e15062/optionx.htm#i1018570) is an option not for compilation, it is for a running jar, so I don't understand how it could copy jar file anywhere? Why don't you just copy agent jar file to root folder? https://stackoverflow.com/questions/8565863/copy-files-to-rootdir-in-gradle. – egorlitvinenko Dec 27 '17 at 07:48
  • I did not say anything about bootclasspath. What I meant was, when I create a spring boot jar using gradle build, it will place the premain class inside the BOOT-INF/classes folder and it will place the agent jar in BOOT-INF/libs folder. Your command line arg does not work with this boot jar layout. – Anindya Chatterjee Dec 27 '17 at 09:02