必须启动 InstrumentationLoadTimeWeaver / openjdk 11

Must start InstrumentationLoadTimeWeaver / openjdk 11

我们有一个生产 Java 1.6 / Tomcat 7 / Spring 4 个应用程序。

我们正在将它移动到 Openjdk 11。这意味着 Spring 5,我认为它也可能包括 Tomcat 9,因为我们正在更新其他所有内容。

问题是不言自明的发音:

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.

一切都很好。唯一的问题是我们已经有了 Spring Insturment Java agent

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

就像我上面说的,这是所有工作代码,我们只是在更新版本。

我确信 LTW 正在加载,因为我们可以看到 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);
    }
}

我只是想不通如何使用 null 检测对其进行实例化。显然我错过了一些东西。可能是一些小而愚蠢的东西。但现在我没主意了。

看来问题出在class加载

  1. 添加 '-verbose:class' 选项以查看 InstrumentationLoadTimeWeaver 是否已加载

  2. 尝试为您添加此选项tomcat上下文配置 <Context> ... <Loader delegate="true"/> ... </Context>

Tomcat 7.0.27 中的一些更改可能会触发此问题

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)