带有 DataSource 的 jetty-env.xml 导致 mvn jetty:run 上的 WebAppContext 失败
Posted
技术标签:
【中文标题】带有 DataSource 的 jetty-env.xml 导致 mvn jetty:run 上的 WebAppContext 失败【英文标题】:jetty-env.xml with DataSource leads to failing WebAppContext on mvn jetty:run 【发布时间】:2012-06-03 18:45:10 【问题描述】:我有一个非常简单的带有 maven 和 jetty 的 webapp 项目,到目前为止一直运行良好。但是现在我需要使用 JNDI 设置 mysql 连接池,因为数据库连接总是超时。
这里首先是我的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>
现在我在文件夹 /src/main/webapp/WEB-INF 中创建了一个 jetty-env.xml,内容如下:
<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>
但问题是我什至无法测试此连接是否有效,因为 jetty-maven-plugin 无法在目标上启动
mvn jetty:run
出现以下错误:
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.
那么我怎样才能让它工作呢?我不得不使用 Jetty 8.x 版,因为我需要 WebSocket 支持,并且远程生产服务器将运行 Jetty 8。
编辑 在 Pavel Veller 回答之前,我尝试了以下操作:将组装好的战争部署到远程 jetty8 服务器并得到相同的错误,只是之前的错误现在如下所示:
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.
所以看起来好像有多个类加载器发生冲突。
EDIT2 按照 Pavel 的要求,我使用简化的 webapp 重新创建了错误,您可以找到 here on Dropbox。这是一个压缩的 Eclipse Maven 项目。
【问题讨论】:
这个问题与数据源无关。我根本没有 jetty-env.xml。 【参考方案1】:尝试删除对 jetty-maven-plugin
的依赖 - 此依赖会将插件添加到您不想要的 WAR 中。
如果您需要使用 Jetty 本身的任何类,请为特定版本的 Jetty(而不是插件)添加一个依赖项,其范围为 provided
。
【讨论】:
这实际上让我更进一步,谢谢。甚至似乎这提高了我对 Maven 的理解;)但是现在我有一个新错误,内容如下:java.lang.NoSuchMethodException: class com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource.setUsername(class java.lang.String)
这是由 <Set name="Username">...
当码头的 XMLConfiguration 解析我的 jetty-env.xml 时引起的。 编辑我打错了,应该是name="User"
。现在它似乎正在工作。非常感谢!
@Conta,好吧,我说你的类路径中有两个版本的码头类 :) 很高兴你解决了它
在与这个问题进行了相当多的斗争之后,这一切都归结为添加 看起来它正在从某个地方拉动 6 号码头。您看到的异常似乎来自解析jetty-env.xml
(org.mortbay.jetty.plus.webapp.EnvConfiguration
) 的代码。 XMLConfiguration
类将您在Configure
元素上声明的类与它从getWebAappContext()
获得的实际类进行比较。后者是 instance of org.mortbay.jetty.plugin.JettyWebAppContext
在您的情况下,您希望它是 org.eclipse.jetty.webapp.WebAppContext
(如果它们都来自同一个“命名空间”,这将是 JettyWebAppContext
的父类)。
很难说这会发生在哪里,但也许检查您的.m2
并确认您有适合您的码头依赖项的二进制文件?它必须运行而不是您期望它运行的版本。
更新。 Jetty 在加载配置中定义的类时会执行以下操作:
-
首先使用
Thread.currentThread().getContextClassLoader()
加载,然后
遍历所有getParent()
,直到用尽所有选项。
如果不成功,尝试使用已加载的类加载器进行加载
码头核心课程 (XmlConfiguration.class.getClassLoader()
)
也循环通过所有的父母。
如果仍然不成功,请执行Class.forName()
如果不成功,报告ClassNotFoundException
。
您可以在 org.mortbay.util.Loader
的代码中看到它(http://grepcode.com 是一个很好的资源,可以快速查看引擎盖)
它确实会加载您的类,但显然不是使用 right 类加载器。
我现在假设您的类路径中某处有一个 extra jetty JAR,它会干扰事物的顺序。
【讨论】:
这听起来是个不错的建议,但同时我在远程生产服务器上尝试了组装战争。它在那里报告相同的错误,但现在报告'org.eclipse.jetty.webapp.WebAppContext' is not of type 'org.eclipse.jetty.webapp.WebAppContext'.
而不是 'org.mortbay.jetty.plugin.JettyWebAppContext' is not of type 'org.eclipse.jetty.webapp.WebAppContext'.
,因此类加载器似乎存在不同的问题。 (现在将这些信息用于最初的问题)
好吧,确保我检查了二进制文件。所有版本都是正确的。我还从 .m2 中删除了下载的 JAR,让 m2e 再次下载它们。没有任何改变。
@Contra,我更新了我的答案,详细说明了 Jetty 如何加载这些类。看看你的 classapth 某处是否有多个码头 JAR。不幸的是,如果无法访问环境,就很难解决此类问题。您和我都知道它应该可以工作(对其他人有用,对吗?)但在您的特定情况下不起作用。您的具体情况一定不完全正确,我们只需要找出它是什么......
为了使这个注释尽可能完整:我的系统上没有设置 CLASSPATH 环境变量。我在整个硬盘驱动器中搜索了 jars。从旧项目中找到 2 个是 jetty 版本 7 并将它们删除。现在我的系统上只有 jetty-**.8.1.0.jar -files。除了 eclipse\plugins 文件夹中的那些,但它们似乎与 stock eclipse 一起提供。而且错误还是一样。
@Contra,在这一点上我希望我能看穿墙壁 :) 也许你可以创建一个你正在部署的 WAR 的精简版本,确保它仍然以同样的方式失败,并且在 Dropbox 上分享它,这样我就可以尝试用我当地的码头自己复制它?【参考方案3】:
遇到了同样的问题:
<useTestClasspath>true</useTestClasspath> (true instead of false)
这在类路径中放置了一个额外的码头罐...
【讨论】:
【参考方案4】:包含依赖范围为我解决了错误。
<scope>provided</scope>
在pom.xml
中是这样的,
<!-- 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>
在码头依赖项中,错误消失了。顺便说一句,我使用的码头版本是9.3.7.v20160115
。
【讨论】:
呃,在哪里?在哪些依赖项中?你能提供更多关于你在哪里插入的上下文吗? @Cheeso 抱歉,我的回答没有详细解释。正如我已经在答案中提到的那样,我将它包含在 pom.xml 下的 jetty-dependencies 下。我已经更新了它。 ;)【参考方案5】:我遇到了同样的问题并修复了它,但不知道为什么。
通过改变
org.eclipse.jetty.webapp.WebAppContext
到
org.eclipse.jetty.maven.plugin.JettyWebAppContext
它出于某种原因开始工作,无法弄清楚究竟是什么原因。显然maven插件与它有关?
【讨论】:
以上是关于带有 DataSource 的 jetty-env.xml 导致 mvn jetty:run 上的 WebAppContext 失败的主要内容,如果未能解决你的问题,请参考以下文章
向 DataSource 添加值时,带有 CollectionView 的 IBDesignable 崩溃
带有补充视图/节标题的 UICollectionView 中的断言失败,dataSource 为 nil?
在 ViewController 中使用带有外部 DataSource 和 UITableView 的自定义 UITableViewCell
为什么带有Form View DataSource的MultiSelectionHelper不会停止?