【问题标题】:Using maven and embedded jetty: ClassCastException使用 maven 和嵌入式码头:ClassCastException
【发布时间】:2010-03-29 14:49:42
【问题描述】:

我有一个用 java 编写的网络应用程序。

我想在嵌入式码头服务器上运行集成测试。

为此,我有一个 Maven 项目(仅用于运行集成测试)。

我使用 cargo-maven2-plugin 进行部署。但是当码头启动时,我收到以下信息:

java.lang.ClassCastException: org.mortbay.jetty.webapp.WebInfConfiguration cannot be cast to org.mortbay.jetty.webapp.Configuration

完整日志:

[beddedLocalContainer] Jetty 6.x Embedded starting...
2010-03-29 16:20:46.615::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
2010-03-29 16:20:46.715::INFO:  jetty-6.1.1rc1
2010-03-29 16:20:46.980::INFO:  Extract jar:file:/C:/Documents%20and%20Settings/Alpha/Local%20Settings/Temp/cargo/conf/cargocpc.war!/ to C:\DOCUME~1\Alpha\LOCALS~1\Temp\Jetty_0_0_0_0_8080_cargocpc.war__cargocpc__xflgf3\webapp
log4j:WARN No appenders could be found for logger (org.apache.jasper.compiler.JspRuntimeContext).
log4j:WARN Please initialize the log4j system properly.
2010-03-29 16:20:47.897::INFO:  Started SelectChannelConnector @ 0.0.0.0:8080
[beddedLocalContainer] Jetty 6.x Embedded started on port [8080]
[cargo:deployer]
[mbeddedLocalDeployer] Deploying [c:\maven-repo\myapp\2.1-SNAPSHOT\myapp-2.1-SNAPSHOT.war]
2010-03-29 16:20:51.711::WARN:  Failed startup of context org.mortbay.jetty.webapp.WebAppContext@132e910{/myapp,c:\maven-repo\myapp\2.1-SNAPSHOT\myapp-2.1-SNAPSHOT.war}
java.lang.ClassCastException: org.mortbay.jetty.webapp.WebInfConfiguration cannot be cast to org.mortbay.jetty.webapp.Configuration
        at org.mortbay.jetty.webapp.WebAppContext.loadConfigurations(WebAppContext.java:801)
        at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:403)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
        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:597)
        at org.codehaus.cargo.container.jetty.Jetty6xEmbeddedLocalContainer.addHandler(Jetty6xEmbeddedLocalContainer.java:294)
        at org.codehaus.cargo.container.jetty.Jetty6xEmbeddedLocalDeployer.deployWebApp(Jetty6xEmbeddedLocalDeployer.java:77)
        at org.codehaus.cargo.container.jetty.internal.AbstractJettyEmbeddedLocalDeployer.deploy(AbstractJettyEmbeddedLocalDeployer.java:95)
        at org.codehaus.cargo.maven2.DeployerDeployMojo.performDeployerActionOnSingleDeployable(DeployerDeployMojo.java:79)
        at org.codehaus.cargo.maven2.AbstractDeployerMojo.performDeployerActionOnAllDeployables(AbstractDeployerMojo.java:104)
        at org.codehaus.cargo.maven2.AbstractDeployerMojo.doExecute(AbstractDeployerMojo.java:47)
        at org.codehaus.cargo.maven2.AbstractCargoMojo.execute(AbstractCargoMojo.java:255)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:556)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:535)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
        at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
        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:597)
        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)

Maven 货物设置:

<profile>
<id>container-cargo-jetty</id>
<properties>
    <skip.test.phase>true</skip.test.phase>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.cargo</groupId>
            <artifactId>cargo-maven2-plugin</artifactId>
            <version>1.0</version>
            <configuration>
                <wait>false</wait>
                <container>
                    <containerId>jetty6x</containerId>
                    <type>embedded</type>
                </container>
                <configuration>
                    <properties>
                        <cargo.servlet.port>8080</cargo.servlet.port>
                        <cargo.logging>medium</cargo.logging>
                    </properties>
                </configuration>
                <deployer>
                    <deployables>
                        <deployable>
                            <groupId>myapp</groupId>
                            <artifactId>myapp</artifactId>
                            <type>war</type>
                            <properties>
                                <context>/myapp</context>
                            </properties>
                        </deployable>
                    </deployables>
                </deployer>
            </configuration>
            <executions>
                <execution>
                    <id>start-container</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                        <goal>deployer-deploy</goal>
                    </goals>
                </execution>
                <execution>
                    <id>stop-container</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>stop</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.mortbay.jetty</groupId>
                    <artifactId>jetty-embedded</artifactId>
                    <version>6.1.22</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

感谢帮助

【问题讨论】:

    标签: maven-2 jetty cargo maven-cargo


    【解决方案1】:

    不支持指定 Cargo 使用的嵌入式 Jetty 的版本(有一个关于此的旧问题,请参阅CARGO-571)。事实上,如果我们查看日志,我们会发现它使用了 jetty-6.1.1rc1:

    2010-03-29 16:20:46.715::INFO:  jetty-6.1.1rc1
    

    因此,首先,删除插件配置中的 jetty 依赖项,这实际上是导致 ClassCastException 的原因。

    但是一旦移除了依赖,我又遇到了另一个不为人知的公共日志记录问题:

    Caused by: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy.  You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.
    

    而且原因似乎是这部分:

                <execution>
                    <id>start-container</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                        <goal>deployer-deploy</goal>
                    </goals>
                </execution>
    

    说实话,我不知道你为什么在这里调用deploy-deploy 目标。没有它,Cargo 会部署声明的deployable。因此,IMO 无需指定此目标。如果你删除它,也不例外(第二个“修复”)。

    总而言之,以下配置有效:

    <profile>
      <id>container-cargo-jetty</id>
      <properties>
        <skip.test.phase>true</skip.test.phase>
      </properties>
      <build>
        <plugins>
          <plugin>
            <groupId>org.codehaus.cargo</groupId>
            <artifactId>cargo-maven2-plugin</artifactId>
            <version>1.0</version>
            <configuration>
              <wait>false</wait>
              <container>
                <containerId>jetty6x</containerId>
                <type>embedded</type>
              </container>
              <configuration>
               <properties>
                 <cargo.servlet.port>8080</cargo.servlet.port>
                 <cargo.logging>medium</cargo.logging>
                </properties>
              </configuration>
              <deployer>
                <deployables>
                  <deployable>
                    <groupId>myapp</groupId>
                    <artifactId>myapp</artifactId>
                    <type>war</type>
                    <properties>
                      <context>/myapp</context>
                    </properties>
                  </deployable>
                </deployables>
              </deployer>
            </configuration>
            <executions>
              <execution>
                <id>start-container</id>
                <phase>pre-integration-test</phase>
                <goals>
                  <goal>start</goal>
                </goals>
              </execution>
              <execution>
                <id>stop-container</id>
                <phase>post-integration-test</phase>
                <goals>
                  <goal>stop</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    

    【讨论】:

    • 如果没有目标'deploy-deploy',将不会部署应用程序。我遇到了 Apache 公共日志记录的类加载器问题。最后我切换到 jetty-maven-plugin。
    • @amra Weird,如果没有deploy-deploy,它确实对我有用(我在发布之前对此进行了测试)。
    【解决方案2】:

    您可能正在处理 JETTY 中的“类加载器地狱”,它使用 JETTY 实例的父类加载器,该类加载器与用于您的 Web 应用程序的类分开,因此即使它们应该是相同的类,但它们不是。

    JETTY 配置中有一些选项可以强制使用相同的类加载器,这可能有助于您的集成测试。

    Classloading - JETTY

    Jetty 提供配置选项 来控制所有这三个选项。 方法 org.mortbay.jetty.webapp.WebAppContext.setParentLoaderPriority(boolean) 允许正常的 java 2 行为 被使用,所有的类都将被加载 如果可能,从系统类路径中。 如果库,这非常有用 Web 应用程序使用的 加载两者的类时出现问题 在 Web 应用程序和系统中 类路径。

    我不确定您如何在 Cargo 中访问 JETTY 配置,但在普通的 JETTY maven 插件中您会执行以下操作:

    <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>7.0.0.pre5</version>
        <configuration>
            <jettyConfig>${jetty.configs}</jettyConfig>
            <reload>manual</reload>
            <contextPath>/</contextPath>
            <webAppConfig>
                <parentLoaderPriority>true</parentLoaderPriority>
    
            </webAppConfig>
        </configuration>
    </plugin>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 2023-04-01
      • 2014-01-14
      • 2014-02-25
      • 2019-09-25
      相关资源
      最近更新 更多