2

I have a camel route fronted with a CXF Web Service consumer (from). I'm deploying in Glassfish 4.0 and this works fine when using the servlet spec 2.4. I now need to enhance the route by adding some persistence along the way which is being done with JPA. Doing this requires an upgrade to servlet spec 2.5+ (I've gone to 3.0)

When the servlet spec is changed to 2.5+ the following error occurs on deployment: java.lang.IllegalStateException: The lifecycle method [finalizeConfig] must not throw a checked exception. Most solutions to this say to remove cxf-rt-transports-http-jetty-2.7.11.jar.

When the jetty jar is removed, the deployment error becomes: java.io.IOException: Could not find destination factory for transport http://schemas.xmlsoap.org/soap/http

Solutions to this, such as CXF BusException No DestinationFactory for namespace http://cxf.apache.org/transports/http OR org.apache.cxf.BusException: No DestinationFactory was found for the namespace http://schemas.xmlsoap.org/soap/http/ say to import the cxf-servlet.xml file which then requires the inclusion of the jar cxf-rt-transports-http-2.7.11.jar (I removed this when I removed the jetty jar). Including these files then gives the following deployment error: java.io.IOException: Cannot find any registered HttpDestinationFactory from the Bus.

The solutions for this error all say to include the jar cxf-rt-transports-http-jetty-2.7.11.jar. This puts me back where I started having to remove it due to the servlet spec upgrade.

I've been able to create a small project to demonstrate this and have included the contents below. I've also tried deploying on Glassfish 4.1 and various combinations of different jar versions (CXF 3.0 excluding the 2.7 jars from camel etc) but I'm still unable to deploy the app in Glassfish.

I'm able to run this with the maven camel plugin 'mvm camel:run' (this requires de-scoping the cxf-rt-transports-http*.jar files from test. Of course this works because I'm outside the glassfish container.

Any help would be greatly appreciated.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>camel-cxf-gf</artifactId>
<packaging>war</packaging>
<version>0.1</version>
<name>Camel with CXF in GF</name>

<properties>
    <camel-version>2.13.1</camel-version>
    <cxf-version>2.7.11</cxf-version>
    <buildNumber>0.1</buildNumber>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${camel-version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-cxf</artifactId>
        <version>${camel-version}</version>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>

    <!-- cxf using slf4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
    </dependency>

    <!-- using Jetty with CXF -->
    <!-- "The Google" says to exclude this when deploying to Glassfish (test scope only) -->
    <!-- To run with mvn camel:run, comment out the test scope on BOTH cxf-rt dependencies -->
    <!-- However, if present for GF deploy, you get the error: The lifecycle method [finalizeConfig] must not throw a checked exception -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>${cxf-version}</version>
        <scope>test</scope>
    </dependency>
    <!-- "The Google" says to exclude this (test scope only) -->
    <!-- To run with mvn camel:run, comment out the test scope on BOTH cxf-rt dependencies -->
    <!-- If present for GF deploy, you get the error: java.io.IOException: Cannot find any registered HttpDestinationFactory from the Bus -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>${cxf-version}</version>
        <scope>test</scope>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        <!-- allows the route to be executed via 'mvn camel:run', NOTE: must comment out the test scope on the cxf-rt-transports dependencies above.... -->
        <plugin>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-maven-plugin</artifactId>
            <version>${camel-version}</version>
            <configuration>
                <fileApplicationContextUri>
                    classpath:META-INF/applicationContext.xml
                </fileApplicationContextUri>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <webXml>web/WEB-INF/web.xml</webXml>
                <failOnMissingWebXml>true</failOnMissingWebXml>
                <archive>
                    <manifestEntries>
                        <Build-Version>${project.version}</Build-Version>
                        <Build-Revision>${buildNumber}</Build-Revision>
                        <Build-Date>${maven.build.timestamp}</Build-Date>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

<display-name>Camel CXF, JMS Web Application</display-name>

<!-- location of spring xml files -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:META-INF/applicationContext.xml</param-value>
</context-param>

<!-- the listener that kick-starts Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

The CXF Service:

package com.example;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(serviceName = "HelloMessage", targetNamespace = "http://example.com/")
public interface HelloMessageEndpoint {
    @WebMethod(operationName = "sayHello")
    @WebResult(name = "messageAnswer", targetNamespace = "http://example.com/", partName = "messageAnswer")
    public String sayHello(@WebParam(name = "name") String name);
}

My applicationContext.xml which contains the Spring DSL camel route (under resources/META-INF):

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cxf="http://camel.apache.org/schema/cxf"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://camel.apache.org/schema/spring 
         http://camel.apache.org/schema/spring/camel-spring.xsd
         http://camel.apache.org/schema/cxf
         http://camel.apache.org/schema/cxf/camel-cxf.xsd
         ">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <!-- This doesn't seem to make a difference -->
    <!--<import resource="classpath:META-INF/cxf/cxf-extension-camel.xml"/>-->
    <!-- When cxf-rt-transports-http is removed (test scope) cxf-servlet.xml is no longer available -->
    <!--<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>-->
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>

    <cxf:cxfEndpoint id="helloMessageEndpoint"
                     address="http://0.0.0.0:9000/HelloWS/"
                     serviceClass="com.example.HelloMessageEndpoint"
                     endpointName="HelloMessageEndpoint"
                     serviceName="HelloMessage"
                     loggingFeatureEnabled="false"/>

    <camelContext id="messageContext" streamCache="true" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="cxf:bean:helloMessageEndpoint"/>
            <log loggingLevel="INFO" message="====> CXF Message Body: ${body}"/>
        </route>
    </camelContext>
</beans>
Community
  • 1
  • 1

1 Answers1

2

As you are using address="http://0.0.0.0:9000/HelloWS/", not the relative path, cxf-rt-transports-http-jetty-2.7.11.jar is need. If you want to use the servlet transport you need to deploy the CXFServlet in you web.xml first, and setup the address of to be relative path, then you should be able to access the CXF endpoint there.

Willem Jiang
  • 3,291
  • 1
  • 14
  • 14