Enabling load-time weaving with Tomcat

Submitted by kofa on Thu, 05/16/2013 - 14:41

I gathered the following information from Spring's documentation (http://static.springsource.org/spring/docs/3.0.x/spring-framework-refer…), the Maven-aspectj plugins's site (http://mojo.codehaus.org/aspectj-maven-plugin/) and the ant task's reference (http://www.eclipse.org/aspectj/doc/next/devguide/antTasks-iajc.html#ant…). Hope you find it useful to have it all in one place.

  1. Disable compile-time weaving in build environment (flag: XterminateAfterCompilation), and have it generate aop-ajc.xml (flag: outxml) to list your own aspects that are compiled:
    1. maven
      <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.4</version>
          [...]
          <executions>
              <execution>
                  <goals>
                      <goal>compile</goal>
                      <goal>test-compile</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <outxml>true</outxml>
              <XterminateAfterCompilation>true</XterminateAfterCompilation>
              [...]
          </configuration>
      </plugin>
      
    2. ant
      <target name="-java-compile" depends="-java-init, -aspectj-init" extensionOf="-do-compile">
          [...]
          <iajc classpathref="compile.class.path"
              aspectpathref="compile.class.path" destdir="${build.dir}/classes"
              source="${javac.source}" target="${javac.target}"
              outxml="true"         XterminateAfterCompilation="true">
              <src refid="source.path"/>
          </iajc>
          [...]
      </target>
      
       
  2. Enable load-time weaving in applicationContext.xml:
    <context:load-time-weaver/>
  3. In context.xml of your webapp, specify the weaving-enabled classloader:
    <Context path="/rm" docBase="rm" reloadable="true" crossContext="false">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
        useSystemClassLoaderAsParent="false"/>
    
  4. Place the jar containing the classloader into server/lib located in your Tomcat's installation directory (CATALINA_HOME). You can have it fetched by Maven, or download it manually from http://maven.springframework.org/release/org/springframework/spring-ins… (not to be confused with http://maven.springframework.org/release/org/springframework/spring-ins…, which is the Java agent that could also be used, effecting the whole JVM, not just a single application)
  5. Create aop.xml where you can specify your weaving options (otherwise, you'll end up weaving all classes loaded by the webapp's classloader, which may not be what you want). Also, you can ask for extra info about weaving (note: generating and printing the extra info is slow, remove it once everything is working):
    <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
    <aspectj>
        <weaver options="-verbose -showWeaveInfo">
            <include within="com.yourcompany..*"/>
        </weaver>
    </aspectj>
    

    As far as I know, you cannot disable compile-time weaving in Eclipse. Maybe this is the solution, I'll have to check: http://wiki.eclipse.org/JDT_weaving_features