开发者

ClassLoader does NOT provide an 'addTransformer(ClassFileTransformer)' method

开发者 https://www.devze.com 2023-03-26 15:05 出处:网络
I\'m using Spring and AspectJ to do some nice weaving and I just ran into this issue after inserting <context:load-time-weaver/> into my application context:

I'm using Spring and AspectJ to do some nice weaving and I just ran into this issue after inserting <context:load-time-weaver/> into my application context:

Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
    at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(DefaultContextLoadTimeWeaver.java:83)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(Abst开发者_如何学编程ractAutowireCapableBeanFactory.java:1419)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1391)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    ... 21 common frames omitted

Do I need a custom JVM to run AspectJ?!? I can't ever remember having to do this before.


I can't find any documentation to support it, but I'm fairly certain that the standard JVM doesn't support Spring's style of load-time weaving. Spring's guide to enabling LTW in different environments implies that this is the case in its "Generic Java applications" section.


You might be using some other LoadTimeWeaver class like in my case it was org.springframework.instrument.classloading.websphere.WebSphereLoadTimeWeaver from spring-context-3.1.1.RELEASE.jar. My problem was spring-instrument-3.1.1.RELEASE.jar was in higher position class hierarchy than the spring-context jar. Which was being used as default agent.

Solution that worked for me: I just brought the instrument jar after spring context in the classpath hierarchy error just vanished.


I want to add a new answer, clarifying some of the misunderstandings caused by both the question and the accepted answer.

Do I need a custom JVM to run AspectJ?!?

Of course not. If you read the error message more carefully, it says (line breaks added):

Caused by: java.lang.IllegalStateException:
  ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an
  'addTransformer(ClassFileTransformer)' method.

  Specify a custom LoadTimeWeaver

  or start your Java virtual machine with Spring's agent:
    -javaagent:org.springframework.instrument.jar

Firstly, "custom LoadTimeWeaver" != "custom JVM". Try not to mix up two things mentioned as alternative solutions (please note the "or" in between them).

Secondly, the alternative solution to a custom weaver is to simply start the JVM with the -javaagent parameter, telling it that you wish to use a Java agent. Quite straightforward.

Now, the accepted answer says:

I can't find any documentation to support it, but I'm fairly certain that the standard JVM doesn't support Spring's style of load-time weaving.

There is also a mix-up of nomenclature here. There is no such thing as "Spring's style of load-time weaving", but there are

  • Spring AOP, a proxy-based "AOP lite" solution designed to work only within Spring and
  • native AspectJ, which can be applied via load-time weaving (LTW) as described in the Spring manual or via compile-time weaving using the AspectJ compiler in your build configuration (e.g. using plugins like AspectJ Maven or Freefair for Gradle). Besides, native AspectJ works in any JVM application, with or without Spring.

Bottom line: no custom JVM, just standard JVM usage plus two alternative AOP frameworks.

0

精彩评论

暂无评论...
验证码 换一张
取 消