In my efforts to integrate Jetty, tomcat and selenium into my Maven build for continuous integration tests, I have run into some strange issues.

It seems that if I run my webapp-2.2.war in my standalone Tomcat 5.5 installation, or in my Maven integrated Jetty, I can refer to my application at my root context of ‘/’ as in http://localhost:8080/index.html
To run my selenium tests I wanted to use tomcat 5.5 through the maven cargo plugin such as:
[cc lang=”xml”] org.codehaus.cargo
cargo-maven2-plugin
0.3.1

${cargo.wait}

${cargo.container}
${project.build.directory}/${cargo.container}.log

${project.build.directory}/${cargo.container}-cargo.log


${cargo.container.url}
${installDir}



${project.build.directory}/${cargo.container}/container ${cargo.host}
${cargo.port}



${pom.groupId}
${pom.artifactId}
war http://${cargo.host}:${cargo.port}/webapp-2.2/cxf





start-container pre-integration-test
start



stop-container post-integration-test
stop


[/cc]

Now this deploys my war that I created just fine. But the strange thing is that is does not deploy to ‘/’, but rather to ‘/webapp-2.2/’ so all of my selenium tests where failing just on this integrated tomcat.

So to get around this, I just added different properties via TestNG for selenium to use in my testng.xml:
[cc lang=”xml”]


[/cc]

Then, the next issue I faced was with the javax.el library issues.
to deploy to Tomcat, I needed to include both el-api and el-ri into may war, but for Jetty, I kept getting the following error:
[cc lang=”bash”] java.lang.LinkageError: Class javax/el/ExpressionFactory violates loader constraints
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:366)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:366)
at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:337)
at javax.el.FactoryFinder.newInstance(FactoryFinder.java:52)
at javax.el.FactoryFinder.find(FactoryFinder.java:162)
at javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:154)
at javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:125)
at org.apache.jasper.runtime.JspApplicationContextImpl.getExpressionFactory(JspApplicationContextImpl.java:80)
at org.apache.myfaces.webapp.Jsp21FacesInitializer.initContainerIntegration(Jsp21FacesInitializer.java:64)
at org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces(AbstractFacesInitializer.java:83)
at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:58)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:539)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1216)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:509)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:447)
at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:110)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
at org.mortbay.jetty.Server.doStart(Server.java:222)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:337)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:279)
at org.mortbay.jetty.plugin.Jetty6RunWar.execute(Jetty6RunWar.java:67)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:447)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:493)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:463)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:311)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:333)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:126)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:282)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
2008-05-08 09:22:37.765::WARN: failed ContextHandlerCollection@da341
[/cc]

The error was because Jetty has it own javax.el libraries, and adding them to my war caused a linkage error. But when running in Tomcat, I need to add both the libraries in order for MyFaces to run.

So to solve this, I took the dependancy declaration for including
[cc lang=”xml”]
javax.el
el-api
${el.version}
compile


javax.el
el-ri
${el.version}
compile

[/cc] and changed it to not include them for the Jetty war which just changes the dependency scope from compile, to provided:
[cc lang=”xml”]
javax.el
el-api
${el.version}
provided


javax.el
el-ri
${el.version}
provided

[/cc] Then to improve on this, I added a profile for jetty to switch the dependency scope by profiles
[cc lang=”xml”] jetty


javax.el
el-api
${el.version}

provided

jetty6x
${env.CATALINA_HOME}
http://dist.codehaus.org/jetty/jetty-6.1.9/jetty-6.1.9.zip
[/cc] then my dependencies would now look like:
[cc lang=”xml”]
javax.el
el-api
${el.version}
${javax.el.scope}


javax.el
el-ri
${el.version}
${javax.el.scope}

[/cc] Now when I want to run Jetty, I just have to use mvn -P jetty jetty:run-war to set my jetty profile as active. I also had to ensure to run mvn clean package first so that I could clean out the el jars before run war.

Mick Knutson

Java, JavaEE, J2EE, WebLogic, WebSphere, JBoss, Tomcat, Oracle, Spring, Maven, Architecture, Design, Mentoring, Instructor and Agile Consulting. http://www.baselogic.com/blog/resume

View all posts

Java / JavaEE / Spring Boot Channel

BLiNC Supporters

BLiNC Adsense

Archives

Newsletter