Translations of this page:

Running our Spring JPA example under Jetty

When I originally wrote this tutorial last year I had trouble getting the examples to run under Jetty. There are two options for Jetty. Either embedded as a Spring Bean which is very useful or as an external web server. First of all we copied the Spring2JPA war to Jetty's webapps directory. Like Tomcat Jetty needs some help with code weaving, this is provided by the generic spring-agent jar (it contains a single class: InstrumentationSavingAgent). Although this class is part of the Spring.jar library it has to be supplied to the JVM via the -javaagent option (new with Java 5). The agent is just a premain() interceptor method and helps with instrumenting classes.

$ java -javaagent:spring-agent.jar -jar start.jar

After starting Jetty I saw this exception.

org.springframework.beans.factory.BeanCreationException:
...
Could not instantiate bean class [org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver]:
Constructor threw exception; nested exception is java.lang.IllegalStateException:
ClassLoader [org.mortbay.jetty.webapp.WebAppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method.
    at
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:230)

Jetty was complaining that my ReflectiveLoadTimeWeaver, that I used with Tomcat lacked the addTransformer method. This method is in InstrumentationLoadTimeWeaver so I modified this in WEB-INF/applicationContext-jpa.xml.

<!-- loadTimeWeaver -->
<property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>

In fact since I wrote the original tutorial Spring 2.5 has been released. This allows the LoadTimeWeaver (LTW) to be auto-detected.

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd ">
 
<context:load-time-weaver/>

This has the big advantage that you can have a generic configuration file for whatever Web Server you decide to use. However this gave the following error on Jetty startup

2008-05-19 17:36:01.890::WARN:  Failed startup of context
org.mortbay.jetty.webapp.WebAppContext@1991ba7{/spring,file:/C:/usr/jetty-6.1.3/webapps/spring/}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver':
Initialization of bean failed; nested exception is java.lang.IllegalStateException:
ClassLoader [org.mortbay.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:spring-agent.jar

So I was back to hand coding the LTW class:

<context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>

Starting the Database server with some initial data and pointing a web browser at:

http://localhost:8000/spring/home.htm

Brings up the Spring2JPA home page.

Resources

tech/java/running-spring-jpa-under-jetty.txt · Last modified: 2008/05/19 17:08 by davidof
Recent changes RSS feed