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

*爱你&永不变心* 提交于 2019-11-29 19:35:39

问题


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.


回答1:


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.




回答2:


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.




回答3:


Had a same issue caused by :

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

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




回答4:


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.




回答5:


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?



来源:https://stackoverflow.com/questions/10800922/jetty-env-xml-with-datasource-leads-to-failing-webappcontext-on-mvn-jettyrun

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!