Использование maven и встроенного причала: ClassCastException - PullRequest
2 голосов
/ 29 марта 2010

У меня есть веб-приложение, написанное на Java.

Я бы хотел провести интеграционные тесты на встроенном сервере Jetty.

Для этой цели у меня есть проект maven (только для запуска интеграционных тестов).

Для развертывания я использую Cargo-Maven2-плагин. Но во время запуска причала я получаю следующее:

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>

спасибо за помощь

Ответы [ 2 ]

2 голосов
/ 30 марта 2010

Указание версии встроенной Jetty, используемой Cargo, не поддерживается (существует старая открытая проблема, см. 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. Поэтому ИМО нет необходимости указывать эту цель. И если вы удалите его, нет никаких исключений (и это второе «исправить»).

Подведем итог, работает следующая конфигурация:

<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>
2 голосов
/ 30 марта 2010

Возможно, вы имеете дело с «адом загрузчика классов» в JETTY, где он использует родительский загрузчик классов для экземпляра JETTY, который отличается от того, который используется для вашего веб-приложения, и поэтому даже если они должны быть идентичными классами, они не являются.

В конфигурации JETTY есть несколько параметров для принудительного использования одного и того же загрузчика классов, который может помочь в ваших интеграционных тестах.

Классная загрузка - JETTY

Jetty предоставляет параметры конфигурации контролировать все три из этих вариантов. Метод org.mortbay.jetty.webapp.WebAppContext.setParentLoaderPriority (булево) позволяет нормальное поведение Java 2 использоваться и все классы будут загружены из системного пути к классам, если это возможно. Это очень полезно, если библиотеки что веб-приложение использует проблемы с загрузкой классов, которые оба в веб-приложении и в системе CLASSPATH.

Я не уверен, как вы получаете доступ к конфигурации JETTY в Cargo, но в обычном плагине 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>
...