title: Instrumenting a maven project using java agent
body: <p>I have been trying to instrument a Java maven project using Java's instrumentation API unsuccessfully. The code for Java agent is (credit to <a href="https://medium.com/javarevisited/java-instrumentation-a-simple-working-example-in-java-a2c549024d9c" rel="nofollow noreferrer">https://medium.com/javarevisited/java-instrumentation-a-simple-working-example-in-java-a2c549024d9c</a>):</p>
  <p><strong>MyAgent.java</strong></p>
  <pre><code>package agent;
  
  import java.lang.instrument.Instrumentation;
  
  public class MyAgent {
      public static void agentmain(String args, Instrumentation instr) {
          System.out.println(&quot;Inside premain.........&quot;);
          instr.addTransformer(new MyTransformer());
      }
  }
  </code></pre>
  <p><strong>MyTransformer.java</strong></p>
  <pre><code>package agent;
  
  import java.io.ByteArrayInputStream;
  import java.lang.instrument.ClassFileTransformer;
  import java.lang.instrument.IllegalClassFormatException;
  import java.security.ProtectionDomain;
  
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.CtMethod;
  
  public class MyTransformer implements ClassFileTransformer {
  
      public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined,
              ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
          byte[] byteCode = classfileBuffer;
  
          //Add instrumentation to Sample class alone
          if (className.equals(&quot;myapp/Sample&quot;)) {
              try {
                  ClassPool classPool = ClassPool.getDefault();
                  CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
                  CtMethod[] methods = ctClass.getDeclaredMethods();
                  for (CtMethod method : methods) {
                      method.insertAfter(&quot;System.out.println(\&quot;adding end line..\&quot;);&quot;);
                  }
                  byteCode = ctClass.toBytecode();
                  ctClass.detach();
              } catch (Throwable ex) {
                  System.out.println(&quot;Exception: &quot; + ex);
                  ex.printStackTrace();
              }
          }
          return byteCode;
      }
  }
  
  </code></pre>
  <p>and pom of Agent is:</p>
  <pre><code>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      &lt;groupId&gt;com.instrumentation.java&lt;/groupId&gt;
      &lt;artifactId&gt;agent&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
          &lt;properties&gt;
          &lt;maven.compiler.source&gt;1.8&lt;/maven.compiler.source&gt;
          &lt;maven.compiler.target&gt;1.8&lt;/maven.compiler.target&gt;
      &lt;/properties&gt;
      &lt;dependencies&gt;
          &lt;!-- https://mvnrepository.com/artifact/org.javassist/javassist --&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.javassist&lt;/groupId&gt;
              &lt;artifactId&gt;javassist&lt;/artifactId&gt;
              &lt;version&gt;3.27.0-GA&lt;/version&gt;
          &lt;/dependency&gt;
  
      &lt;/dependencies&gt;
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                  &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
                  &lt;configuration&gt;
                  &lt;descriptorRefs&gt;
                  &lt;descriptorRef&gt;jar-with-dependencies&lt;/descriptorRef&gt;
              &lt;/descriptorRefs&gt;
                      &lt;archive&gt;
                          &lt;manifest&gt;
                              &lt;addDefaultImplementationEntries&gt;
                                  true&lt;/addDefaultImplementationEntries&gt;
                              &lt;addDefaultSpecificationEntries&gt;
                                  true&lt;/addDefaultSpecificationEntries&gt;
                          &lt;/manifest&gt;
                          &lt;manifestEntries&gt;
                              &lt;Premain-Class&gt;agent.MyAgent&lt;/Premain-Class&gt;
                              &lt;Can-Redefine-Classes&gt;false&lt;/Can-Redefine-Classes&gt;
                              &lt;Can-Retransform-Classes&gt;true&lt;/Can-Retransform-Classes&gt;
                          &lt;/manifestEntries&gt;
                      &lt;/archive&gt;
                  &lt;/configuration&gt;
                  &lt;executions&gt;
              &lt;execution&gt;
                  &lt;id&gt;make-assembly&lt;/id&gt;
                  &lt;!-- this is used for inheritance merges --&gt;
                  &lt;phase&gt;package&lt;/phase&gt;
                  &lt;!-- append to the packaging phase. --&gt;
                  &lt;goals&gt;
                      &lt;goal&gt;single&lt;/goal&gt;
                      &lt;!-- goals == mojos --&gt;
                  &lt;/goals&gt;
              &lt;/execution&gt;
          &lt;/executions&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  <p>And the pom of the project I am trying to instrument is:</p>
  <pre><code>&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      &lt;groupId&gt;com.example.java&lt;/groupId&gt;
      &lt;artifactId&gt;myapp&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;properties&gt;
          &lt;maven.compiler.source&gt;1.8&lt;/maven.compiler.source&gt;
          &lt;maven.compiler.target&gt;1.8&lt;/maven.compiler.target&gt;
      &lt;/properties&gt;
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                  &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
                  &lt;version&gt;2.4&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;archive&gt;
                          &lt;manifest&gt;
                              &lt;addClasspath&gt;true&lt;/addClasspath&gt;
                              &lt;mainClass&gt;myapp.Sample&lt;/mainClass&gt;
                          &lt;/manifest&gt;
                      &lt;/archive&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  <p>Creating jar files for both projects and then running the jar file with argument <code>-javaagent:agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar</code> works.</p>
  <p>However, when I include the jar file of the java agent under the working directory of the target project and use <code>-Dexec.args=&quot;-javaagent:agent-0.0.1-SNAPSHOT-jar-with-dependencies.jar&quot;</code>, the project does not get instrumented and Maven does not throw any error.</p>
  <p>Therefore, is it possible to instrument a Maven project when it is not compiled into a jar file like this?</p>
  <p>Many thanks in advance</p>