Search code examples
javaintellij-ideanoclassdeffounderrorjavaagents

Java Agent (Instrumentation API) java.lang.NoClassDefFoundError in IntelliJ IDEA When Packaging Libraries


While creating and using an agent for the first time, I was successful. I created a basic Java app to use my agent on for debugging, and my agent received the bytecode as expected. I then proceeded to add javassist to my project libraries, and added some relevant code to use javassist as well. I added javassist to my artifact(Using IntelliJ IDEA), so that it would be packaged inside the jar with my agent. I found that nothing happened at all after my changes from javassist were to be made in my code. I then proceeded to debug with print statements and found that the code was indeed not running. Knowing this, I put a try catch statement around the code and found that there is a java.lang.NoClassDefFoundError happening within my java agent which was not being broadcasted without the try catch statement. After this, I tried making my own little library jar with simple code, and it too did not work when packaged with my agent. Trying and trying, I can't even get my agent to work with libraries placed alongside the agent's jar. The only option I can think of to get this to work is to directly drop the source of the library into my project and use it.

Below are the classes I am using:

Agent Main Class:

package poisonedporkchop.agent;

import java.lang.instrument.Instrumentation;

public class Agent {
    public static void premain(String args, Instrumentation instrumentation){
        AgentClassTransformer transformer = new AgentClassTransformer();
        System.out.println("Injecting/editing jar...");
        instrumentation.addTransformer(transformer);
    }
}

Agent Transformer Class:

package poisonedporkchop.agent;

import testpackage.TestClass;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

public class AgentClassTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytecode) throws IllegalClassFormatException {
        System.out.println("Class Received: " + className);
        if(className.equals("poisonedporkchop/testapp/Main"))
        {
            try {
                System.out.println("Main found!");
                System.out.println("Test if it it even getting here."); //Nothing after this works.
                TestClass test = new TestClass();
                System.out.println("T1");
                test.testMethod();
                System.out.println("T2");
                System.out.println(TestClass.testStatic);
                System.out.println("Test if it is getting to the end.");
            }
            catch (Throwable e)
            {
                e.printStackTrace();
            }
        }
        return bytecode;
    }
}

Manifest: (Custom manifest is required for an agent)

Manifest-Version: 1.0
Premain-Class: poisonedporkchop.agent.Agent

IntelliJ IDEA Version: 2017.2.6 (build 172.4574.11)

IntelliJ Project Setup:

Project Setup

Module Setup

I am bewildered as of what to do. Note that I have added the library into the jar in the artifacts, as many solutions similar to my problem say to do. Any guidance would be appreciated.


Solution

  • I found out by messing around, that the solution in the problem does indeed lie in extracting the source code of the library to your jar.

    The way to do this in IntelliJ IDEA is by the following:

    Right click your library in Artifacts and select this option

    Doing this allows you to use your libraries without getting any NoClassDefFoundError's.