可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
can't seem to have my spring webapp working with jetty-maven pluging
i always get
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.eclipse.jetty.webapp.WebAppClassLoader] 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
though i have:
- set MAVEN_OPTS to javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
- set JAVA_OPTIONS to the same thing
- added dep to spring-instrument and spring-aspects
- added
jvmArgs
with -javaagent:....
to jetty-maven-plugin configuration
回答1:
Probably you are missing few jars aspectjweaver
aspectjrt
spring-instrument
Additionally you may want to try explicitly defining the bean loadTimeWeaver
in applicationcontext.xml file.
<property name="loadTimeWeaver">
<bean id="instrumentationLoadTimeWeaver" class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
回答2:
When launching Jetty from Maven (using mvn jetty:run), Jetty will run in the same JVM as maven does, so you'll need to pass any options using MAVEN_OPTS.
(Be sure to include the minus sign before javaagent, as I didn't see that in your snippet).
export MAVEN_OPTS=-javaagent:org.springframework.instrument-3.0.5.RELEASE.jar
A complete example of load time weaving in jetty using Maven can be found on Github.
https://github.com/zzantozz/testbed/tree/master/spring-aspectj-load-time-weaving-in-jetty
回答3:
Without more details about your pom.xml file... it's not easy. But one common issue with jetty plugin are the dependencies.
One rule that always worked for me is to put all dependencies of your war with scope provided as direct dependencies of the maven-jetty-plugin.
I suggest you to put spring-instrument and spring-aspects as direct dependencies of the maven-jetty-plugin too.
According my understanding:
set MAVEN_OPTS to javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
is the correct way to pass jvm args to the jetty JVM (since jetty run in the same JVM as maven)
回答4:
I've had same issue I use load time weaving in spring. How can i set class loader in jetty?. I've resolved it by adding a "-Xbootclasspath/a:[path to jar]" as JvmArgs param.
Now it's looks like
<extraJvmArgs>-Xmx4g -XX:MaxPermSize=512m -javaagent:C:\Users\auldanov\.m2\repository\org\springframework\spring-instrument\3.1.4.RELEASE\spring-instrument-3.1.4.RELEASE.jar -Xbootclasspath/a:C:\Users\auldanov\.m2\repository\org\springframework\spring-instrument\3.1.4.RELEASE\spring-instrument-3.1.4.RELEASE.jar</extraJvmArgs>
回答5:
I finally made it work following the example from ddewaele. So apart from doing
- set MAVEN_OPTS to
javaagent:/Users/blabla/.m2/repository/org/springframework/spring-instrument/3.1.3.RELEASE/spring-instrument-3.1.3.RELEASE.jar
You have to check the dependencies you have added. I was missing spring-tx. You need to have these dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<!-- Following dependencies are required because of spring-aspects -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
Otherwise you get that non-intuitive error
Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
NOTE: You can use the spring version you want. I am using 3.2.5 for everything.
回答6:
Want to warn everybody! This problem is very unclear.
Don't include this dependency to your project or include with provided scope.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${thirdparty.spring.version}</version>
</dependency>
Otherwise agent class InstrumentationSavingAgent will load twice (first when loading agent, second while linking libraries) and spring will use second Class instance without injected Instrumentation