jetty-env.xml with DataSource leads to failing WebAppContext on mvn jetty:run
Asked Answered
M

5

7

I have a really simple webapp project with maven and jetty that has been working very well until now. But now I need to setup MySQL connection pooling with JNDI as the database connections always time out.

First of all here is the relevant content of my pom.xml:

<modelVersion>4.0.0</modelVersion>
...
<packaging>war</packaging>
...
<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jetty-version>8.1.0.v20120127</jetty-version>
</properties> 
<dependencies>
    ...
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.20</version>
    </dependency>
    <dependency>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>${jetty-version}</version>
        <type>maven-plugin</type>
    </dependency>
</dependencies>
...
<build>
    <plugins>
    <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>${jetty-version}</version>
        <configuration>
                <scanIntervalSeconds>10</scanIntervalSeconds>
            </configuration>
        </plugin>
    </plugins>
    ...
</build>

Now I created a jetty-env.xml in the folder /src/main/webapp/WEB-INF with the following content:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">  
    <New id="project-db" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg>jdbc/db</Arg>
        <Arg>
            <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
                <Set name="url">jdbc:mysql://www.example.com:3306/mydb</Set>
                <Set name="username">dbuser</Set>
                <Set name="password">dbpass</Set>
            </New>
        </Arg>
    </New>
</Configure>

But the problem is that I can't even test if this connection works as the jetty-maven-plugin fails to start on the goal

mvn jetty:run

with the following error:

WARN:oejw.WebAppContext:Failed startup of context o.m.j.p.JettyWebAppContext
{/,file:/D:/documents/programmierung/workspace/battleships-trunk/src/main/webapp/}
,file:/D:/documents/programmierung/workspace/battleships-trunk/src/main/webapp/

java.lang.IllegalArgumentException: Object of class 
'org.mortbay.jetty.plugin.JettyWebAppContext' is not of type 
'org.eclipse.jetty.webapp.WebAppContext'. 
Object Class and type Class are from different loaders.

So how can I get this to work? I'm forced to use Jetty version 8.x as I need WebSocket support and as the remote productive server will be running Jetty 8.

EDIT Before Pavel Veller's answer I tried the following: Deployed the assembled war to the remote jetty8 server and got the same error only that the previous error now reads as follows:

java.lang.IllegalArgumentException: Object of class 
'org.eclipse.jetty.webapp.WebAppContext' is not of type 
'org.eclipse.jetty.webapp.WebAppContext'. 
Object Class and type Class are from different loaders.

So it seems as if there are multiple class loaders conflicting.

EDIT2 As requested by Pavel I recreated the error with a simplified webapp which you can find here on Dropbox. It is a zipped eclipse maven project.

Mew answered 29/5, 2012 at 14:11 Comment(1)
This problem has nothing to do with data source. I don't have jetty-env.xml at all.Platinous
T
7

Try removing the dependency on jetty-maven-plugin- this dependency adds the plugin to the WAR, which you don't want.

If you need to use any classes from Jetty itself, add a dependency for the specific version of Jetty (rather than the plugin) with a scope of provided.

Tyronetyrosinase answered 30/5, 2012 at 7:57 Comment(3)
That actually got me a step further, thanks. Even seems as if this improved my understandment of Maven ;) However now I have a new error which reads as follows: java.lang.NoSuchMethodException: class com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource.setUsername(class java.lang.String) which is caused by <Set name="Username">... when jetty's XMLConfiguration parses my jetty-env.xml. EDIT Well I mistyped, it should read name="User". Now it seems to be working. Thanks a lot!Mew
@Conta, well, I said you had two version of jetty classes somewhere on your classpath :) glad you have it resolvedGlanti
After quite a bit of struggle with this very issue it all came down to adding <scope>provided</scope>. Thanks!Pegues
G
1

It looks like it's pulling jetty 6 from somewhere. The exception you're seeing seems to be coming from the code that parses jetty-env.xml (org.mortbay.jetty.plus.webapp.EnvConfiguration). The XMLConfiguration class compares the class you declare on the Configure element with the actual class of what it gets from getWebAappContext(). The latter is instance of org.mortbay.jetty.plugin.JettyWebAppContext in your case and you expect it to be org.eclipse.jetty.webapp.WebAppContext (which would be the parent class for JettyWebAppContext had they both come from the same "namespace").

It's hard to tell where that would be happening from but maybe inspect your .m2 and confirm you have the proper binaries for your jetty dependencies? It has got to be running not the version you expect it to run.

UPDATE. Jetty does the following when it loads the classes defined in the configuration:

  1. first load with Thread.currentThread().getContextClassLoader() and loop through all getParent() until all options are exhausted.
  2. if not successful, attempt to load with the class loader that loaded jetty core classes (XmlConfiguration.class.getClassLoader()) looping through all the parents as well.
  3. If still not successful, do a Class.forName()
  4. Report ClassNotFoundException if not successful.

you can see it in the code of org.mortbay.util.Loader(http://grepcode.com is a great resource for a quick look under the hood)

It does load the class in your case, but apparently not with the right class loader.

I would now assume you have an extra jetty JAR somewhere on your classpath that interferes with the order of things.

Glanti answered 29/5, 2012 at 19:6 Comment(7)
That sounds like a good suggestion but in the meantime I tried the assembled war on the remote productive server. There it reports the same error but instead of 'org.mortbay.jetty.plugin.JettyWebAppContext' is not of type 'org.eclipse.jetty.webapp.WebAppContext'. it now reports 'org.eclipse.jetty.webapp.WebAppContext' is not of type 'org.eclipse.jetty.webapp.WebAppContext'. so there seems to be a different problem with the class loaders. (Taking that info to initial question now)Mew
Well, to be sure I checked the binaries. All versions are correct. I also deleted the downloaded JARs from .m2 and let m2e download them again. Nothing changed.Mew
@Contra, I updated my answer with the details about how Jetty loads those classes. see if you have more than one jetty JAR on your classapth somewhere. Unfortunately, questions like this one are hard to troubleshoot without having access to the environment. You and I know that it should be working (it has for other people, right?) but it doesn't work in your particular case. Something must be not exactly right with your particular case and we just need to find out what it is...Glanti
To make this comment as complete as possible: I have no CLASSPATH environment variable set on my system. I searched the complete hard drive for jars. Found 2 which were jetty version 7 from an older project and removed them. Now there are only jetty-**.8.1.0.jar -files on my system. Except the ones in eclipse\plugins folder but they seem to come with stock eclipse. And the error is still the same.Mew
@Contra, at this point I wish I could see through the walls :) maybe you can create a stripped down version of the WAR you're deploying, ensure it still fails in the same way, and share it on Dropbox so I can try to reproduce it myself with my local jetty?Glanti
@Contra, may I also ask you to run jetty in the VERBOSE logging mode (docs.codehaus.org/display/JETTY/Debugging) and post the logs somewhere for us to look at?Glanti
Well I was able to recreate the error with this simplest webapp. Uploaded it on Dropbox as requested. The zip contains the complete eclipse project. I'd also like to add the complete log but I seriously couldn't find out how to configure the jetty-maven-plugin to work in verbose mode. (I have added the link to the project to the initial question too)Mew
S
0

Had a same issue caused by :

<useTestClasspath>true</useTestClasspath> (true instead of false)

That put a extra jetty jar in the classpath...

Seessel answered 30/9, 2013 at 10:8 Comment(0)
P
0

Including the dependency scope solved the error for me.

<scope>provided</scope>

In the pom.xml it looks like this,

<!-- JETTY DEPENDENCIES -->
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-server</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-servlet</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-webapp</artifactId>
  <version>${jetty.version}</version>
  <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlets</artifactId>
    <version>${jetty.version}</version>
    <scope>provided</scope>
</dependency>

in the jetty dependencies and the errors went off. And btw, the jetty version I'm using is 9.3.7.v20160115.

Platinous answered 29/6, 2015 at 11:5 Comment(2)
uh, where? In which dependencies? Can you provide some more context for where you inserted this?Travers
@Travers Sorry that my answer wasn't explaining it in detail. As I've mentioned it already in the answer, I included it under the jetty-dependencies under pom.xml. I've updated it. ;)Platinous
B
-1

I had the same issue and fixed it but can't figure out why.

By changing

org.eclipse.jetty.webapp.WebAppContext

to

org.eclipse.jetty.maven.plugin.JettyWebAppContext 

it started to work for some reason, can't figure out exactly why. Clearly maven plugin has something to do with it?

Brokendown answered 3/8, 2014 at 16:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.