I am trying to develop a javaagent that would instrument code with help of asm-4. For now I'm stucked with a pretty basic problem, the classloader for the javaagent doesn't see asm dependencies and therefor fails. Do I have to provide a jar-with-dependencies (aka maven build plugin) which contains all the needed classes by the agent, or is there another way to add classes to the java agent? Referencing the jar asm-all.jar directly in the classpath didn't help. Building jar-with-dependencies didn't help at first, because Premain-Class attribute couldn't be set with assembly plugin. Help is appreciated ;-)
- 
                    1ok, apparently I found the answer myself:test.agent.MyAgent 
- 
                    1please write it as answer and accept it, so that the other users can see the answer of your question. – aphex Apr 08 '13 at 06:53
5 Answers
ok, found it by experimenting. The dependent classes should be part of the jar, which can be created by maven assembly plugin, for example:
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <index>true</index>
                <manifest>
                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                </manifest>
                <manifestEntries>
                    <Premain-Class>test.agent.MyAgent</Premain-Class>
                </manifestEntries>
            </archive>
        </configuration>
        <executions>
            <execution>
                <id>make-assembly</id>
                <!-- this is used for inheritance merges -->
                <phase>package</phase>
                <!-- append to the packaging phase. -->
                <goals>
                    <goal>single</goal>
                    <!-- goals == mojos -->
                </goals>
            </execution>
        </executions>
    </plugin>
Use the jar as javaagent path and everything works fine.
 
    
    - 1,141
- 1
- 10
- 25
I followed this blog post. Here is how I made it work, to get the size of objects.
/MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: ar.com.docdigital.InstrumentationApp
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true
in your pom.xml (Note we reference custom MANIFEST)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifestFile>
                MANIFEST.MF
            </manifestFile>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>
                    ar.com.docdigital.App
                </mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>
My Instrumentation Agent:
package ar.com.docdigital;
import java.lang.instrument.Instrumentation;
/**
 *
 * @author juan.fernandez
 */
public class InstrumentationApp {
    private static Instrumentation instrumentation;
    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }
    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}
My main App:
package ar.com.docdigital;
import static ar.com.docdigital.InstrumentationApp.getObjectSize;
/**
 *
 * @author juan.fernandez
 */
public class App {
    public static void main (String[] args) {
        System.out.println("Size of CoprimeLong: " + getObjectSize(new CoprimesList.CoprimeLong(1L)));
        System.out.println("Size of Long: " + getObjectSize(new Long(1L)));
    }
}
Putting all together & CLI output:
$ mvn package
$ java -javaagent:target/primos-0.1.0-SNAPSHOT.jar -jar target/primos-0.1.0-SNAPSHOT.jar 
  Size of CoprimeLong: 24
  Size of Long: 24
 
    
    - 2,002
- 2
- 26
- 28
I used maven-jar-plugin for my CustomAgent. I dont have any dependent modules/jars so using an assembly plugin is an overkill.
<build>
    <sourceDirectory>src</sourceDirectory>
    <finalName>are-agent</finalName>
    <plugins>           
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                        <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                    </manifest>
                    <manifestEntries>
                        <Premain-Class>are.agent.CustomAgent</Premain-Class>
                        <Can-Redefine-Classes>false</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
<build>
 
    
    - 1,088
- 9
- 19
I think you can specify Class-Path in the Manifest.mf file in the MyAgent.jar.
 
    
    - 8,619
- 7
- 36
- 40
You should add Premain-Class entry to the manifest. I use gradle to build Java projects.
Add this to gradle.build
jar {
    manifest {
        attributes(
                "Premain-Class": "com.training.agent.agentapp.SimplestAgent",
                "Can-Redefine-Classes": false,
                "Can-Set-Native-Method-Prefix": false
        )
    }
}
And then you can run it
java -javaagent:agent.jar -jar application.jar
 
    
    - 12,225
- 15
- 76
- 114