Search code examples
javaspringtomcatspring-dataeclipselink

Must start InstrumentationLoadTimeWeaver / openjdk 11


We have a production Java 1.6 / Tomcat 7 / Spring 4 application.

We are moving it to Openjdk 11. This means Spring 5 and I figure it might as well include Tomcat 9 since we're updating everything else.

The problem is the self explanatory sounding:

ERROR org.springframework.web.context.ContextLoader - Context initialization failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rootContextConfig': Unsatisfied dependency expressed through field 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in com.xxxxx.config.RootContextConfig: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.

All well and good. Only problem is that we already have the Spring Insturment Java agent

-javaagent:${CATALINA_HOME}/lib/spring-instrument-5.1.5.RELEASE.jar

Like I said above this is all working code we are just updating versions.

I am confident the LTW is being loaded because we can see the error being produced by InstrumentationLoadTimeWeaver class.

@Override
public void addTransformer(ClassFileTransformer transformer) {
    Assert.notNull(transformer, "Transformer must not be null");
    FilteringClassFileTransformer actualTransformer =
            new FilteringClassFileTransformer(transformer, this.classLoader);
    synchronized (this.transformers) {
        Assert.state(this.instrumentation != null,
                "Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.");
        this.instrumentation.addTransformer(actualTransformer);
        this.transformers.add(actualTransformer);
    }
}

I just can't figure out how it can get instantiated with a null instrumentation. Obviously I'm missing something. Probably something small and stupid. But right now I'm out of ideas.


Solution

  • It seems that problem is with classloading

    1. Add '-verbose:class' option to see if InstrumentationLoadTimeWeaver was loaded

    2. try to add this option to you tomcat contexct configuration <Context> ... <Loader delegate="true"/> ... </Context>

    There were some changes in Tomcat 7.0.27 which can trigger this problem

    Make the implementation of Catalina.getParentClassLoader consistent with similar methods across the code base and have it return the system class loader if no parent class loader is set. (markt)