gif animé ordinateur

mercredi 6 novembre 2013

ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method

I am actually working on some web application under Tomcat 6 and SPRING, and try to bind some Spring-Aop aspect to inspect some business events. So i faced some configuration problem and had to google longtime before everything worked correctly.
So i want to share this post with all this may concern
First of all, i used tomcat6 as MAVEN plugin,
Starting my tomcat6 throws the exception bellow :
org.springframework.beans.factory.BeanCreationException : Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.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

and the cause is : java.lang.IllegalStateException : ClassLoader [org.apache.catalina.loader.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


To correct this, just add  to your web module pom.xml the flowing yellow color xml tags :

<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<contextFile>${conf.tomcat}</contextFile>
<path>/myAppPath</path>
<uriEncoding>UTF-8</uriEncoding>
<useTestClasspath>true</useTestClasspath>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
<classLoaderClass>org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader</classLoaderClass>
</configuration>
<dependencies>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument-tomcat</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</plugin>

 Dont forget to add the spring-instrument-tomcat, dependency, otherwise it 'll not work.
This is what Spring authors proposed to you :

Tomcat's default class loader does not support class transformation which is why Spring provides an enhanced implementation that addresses this need. Named TomcatInstrumentableClassLoader, the loader works on Tomcat 5.0 and above and can be registered individually for each web application as follows:
  • Tomcat 6.0.x or higher
    1. Copy org.springframework.instrument.tomcat.jar into $CATALINA_HOME/lib, where $CATALINA_HOME represents the root of the Tomcat installation)
    2. Instruct Tomcat to use the custom class loader (instead of the default) by editing the web application context file:
      <Context path="/myWebApp" docBase="/my/webApp/location">
          <Loader
              loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
      </Context>
      Apache Tomcat 6.0.x (similar to 5.0.x/5.5.x) series supports several context locations:
      • server configuration file - $CATALINA_HOME/conf/server.xml
      • default context configuration - $CATALINA_HOME/conf/context.xml - that affects all deployed web applications
      • per-web application configuration which can be deployed either on the server-side at $CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml or embedded inside the web-app archive at META-INF/context.xml
For efficiency, the embedded per-web-app configuration style is recommended because it will impact only applications that use the custom class loader and does not require any changes to the server configuration. See the Tomcat 6.0.x documentation for more details about available context locations. 

This SPRING solution didn't fill your need if you are using TOMCAT as MAVEN plugin.

Now Configure your spring xml context by adding some XML tags

<?xml version="1.0" encoding="UTF-8"?>
beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd"

>

<!-- HERE ADD MORE CONF AND BEAN DECLARATION-->
 

<!--
Activates various annotations to be detected in bean classes: Spring's
@Required and @Autowired, as well as JSR 250's @Resource.
-->
<context:annotation-config />

<aop:aspectj-autoproxy />
<context:load-time-weaver/>
</
beans>.

Now that your Spring is correctly configured, you can create your SPRING AOP Classes, may be by @Aspect, @PointCut  Annotation ...etc.

Hope this 'll help.