I'v created a SOAP webservice and I'd like to expose it with camel-cxf on wildfly.
When I want to deploy it I get the following error:
Apache CXF library (cxf-core-3.2.0.jar) detected in ws endpoint deployment; either provide a proper deployment replacing embedded libraries with container module dependencies or disable the webservices subsystem for the current deployment adding a proper jboss-deployment-structure.xml descriptor to it. The former approach is recommended, as the latter approach causes most of the webservices Java EE and any JBossWS specific functionality to be disabled.
Tried what was suggested here but didn't work. Tried to exclude the cxf dependencies from the caml-cxf include in my pom.xml:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.20.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.cxf</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
That solved the error but produces new ones:
Failed to define class org.apache.camel.component.cxf.spring.AbstractCxfBeanDefinitionParser in Module "deployment.CamelCXF-1.0.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/AbstractCxfBeanDefinitionParser
Failed to define class org.apache.camel.component.cxf.spring.CxfEndpointBeanDefinitionParser in Module "deployment.CamelCXF-1.0.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser
Context initialization failed: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/camel.xml]; nested exception is org.springframework.beans.FatalBeanException: Invalid NamespaceHandler class [org.apache.camel.component.cxf.spring.NamespaceHandler] for namespace [http://camel.apache.org/schema/cxf]: problem with handler class file or dependent class; nested exception is java.lang.NoClassDefFoundError: Failed to link org/apache/camel/component/cxf/spring/CxfEndpointBeanDefinitionParser
Could you help me resolve these errors or provide a small working example that I can deploy on wildfly and extend? Much appreciated.
Defined these dependencies in my pom.xml:
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.20.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.cxf</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
And here's my camel.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xsi:schemaLocation="
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<cxf:cxfEndpoint id="customerEndpoint"
address="http://localhost:8080/TestService/"
serviceClass="my.package.TestService"
wsdlURL="WEB-INF/CustomerService.wsdl"/>
<bean id="logBean" class="my.package.LogBean"/>
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:customerEndpoint" />
<to uri="bean:logBean" />
</route>
</camel:camelContext>
Follow-up question
I could set up a webservice with the links provided by #Tadayoshi Sato. The examples, however, only use one simple function with one processor. How do I know which function was called when I have several operations in a port definition?
Is it possible to have camel call the implementation of the provided interface that was called or do I have to map that myself?
As Claus pointed out, the most recommended approach to use Camel on WildFly is using WildFly Camel. You can find in the link below how to install the WildFly Camel subsystem to WildFly:
http://wildfly-extras.github.io/wildfly-camel/index.html
Once you've installed WildFly Camel, let's see this link, where you can find how to develop code using camel-cxf on WildFly:
http://wildfly-extras.github.io/wildfly-camel/index.html#_jax_ws
The point is that WildFly already has its own CXF libraries as a subsystem and you are required to use the built-in libraries as much as possible; otherwise, you may encounter awkward problems like those in the question. It's the WildFly Camel subsystem that lets you to use the underlying WildFly subsystems for your Camel applications.
UPDATE:
For camel-cxf consumers, the operation name which is called is available via CxfConstants.OPERATION_NAME message header. According to:
https://github.com/apache/camel/blob/master/components/camel-cxf/src/main/docs/cxf-component.adoc
The camel-cxf endpoint consumer POJO data format is based on the CXF invoker, so the message header has a property with the name of CxfConstants.OPERATION_NAME and the message body is a list of the SEI method parameters.
You may route a message based on this message header and change the implementations accordingly.
Related
I'm using Arquillian and TomEE embedded adapter to test a WAR.
In my pom.xml I have the following entry
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>1.7.2</version>
<scope>test</scope>
</dependency>
and in my arquillian.xml I have the following
<container qualifier="tomee" default="true">
<configuration>
[...]
<property name="javaVmArguments">-Xms2048m -Xmx2048m</property>
<property name="singleDumpByArchiveName">true</property>
<!--<property name="singleDeploymentByArchiveName">true</property>-->
[...]
</configuration>
</container>
Adding the property singleDumpByArchiveName I expected that, dumping only once the web archive for all the tests, there would be an improvement in terms of execution time, but that did not happen.
I also tried to add the Arquillian Suite Extension with the same goal
<dependency>
<groupId>org.eu.ingwar.tools</groupId>
<artifactId>arquillian-suite-extension</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
but I get the following error
java.lang.NoSuchMethodError: org.jboss.arquillian.test.spi.TestResult.setEnd(J)V
Do you have any tip on how to make these solutions work or can you suggest others to speed up the tests execution time?
first of all:
<property name="javaVmArguments">-Xms2048m -Xmx2048m</property>
is not a tomee configuration since tomee embedded doesn't fork a JVM, probably something copied/pasted from the net.
Then your error probably just means you have a dependency conflict (tomee brings an older version of arquillian). You need to fix that. You can need to use tomee 1.7.4 (or 7.x) which is compatible with arquillian > 1.1.11
I'm trying to use Jersey and it's integration with Spring, in order to have jax-rs endpoints in our spring web-app.
The problem I have is that members of the application that are annotated with #Value isn't populated in our unit tests.
The ones that are populated with #Autowired works fine, and if I create a setter method for the string and annotate that with #Value that also works.
What annoys me is that members annotated directly with #Value doesn't work in the test, but work when deployed in our tomcat.
Is this a problem with our test configuration somehow? Or is this a known issue somewhere?
These are the relevant dependencies I think:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<scope>test</scope>
</dependency>
A small project that examplifies the problem here:
https://github.com/alexanderkjall/jersey-jetty-interaction-example/blob/master/src/main/java/no/hackeriet/bugs/SpringRequestResource.java
Seems to be you might be missing component-scan, After adding it worked fine for me.
<context:component-scan base-package="no.hackeriet.bugs" />
but I am not sure how it still worked in tomcat without component-scan, which quite puzzles me.
A Spring web application is just a normal web application using servlet API 3.0.
In servlet API 3.0 web.xml file is optional (most of the time).
I' ve tried not to include web.xml inside my Spring aplication,but somehow it seems to be required even using Servlet 3.0
The only difference between a Spring applications and web apps I've run successfully without writing a web.xml file, is that in Spring filters and servlets are defined inside jars in the lib folder.
Any clues why this happens ?
You can't just exclude the web.xml, as you (at least) need to define which version of the Servlet API are you using.
At the minimum, you'd need this in your 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">
Everything else (servlets, filters, etc.) can be configured with annotations.
Fortunately, you can create completely XML free Spring applications nowadays.
There are various different options for such configs with or without Spring Boot.
With pure Spring you can use AbstractAnnotationConfigDispatcherServletInitializer
With Spring Boot, you can have SpringBootServletInitializer.
This is my Github repository with bunch of projects based on both approaches.
Version of servlets is defined by Servlet API you have on your classpath. E.g.:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>
or
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
You also don't specify servlets, as Spring has own implementation of servlet DispatcherServlet.
Filters are registered as beans into Spring context.
I recently switched to Apache log4j2, and still can not find a way to configure hibernate logging using log4j2.xml.
Because I can not find a way around this problem I still use log4j.properties file explicitly for hibernate. This is not the best solution since my log4j2.xml uses JPA appender (writes logs to db). I do not want to write separate logic for hibernate.
Is there a way to configure hibernate logging using log4j2?
As suggested in
https://issues.apache.org/jira/browse/LOG4J2-172
you can add system property to force hibernate use slf4j
-Dorg.jboss.logging.provider=slf4j
also log4j-slf4j-impl should be added to classpath
My custom solution:
with Spring you can place
org.jboss.logging.provider=slf4j
in property file
(envConfigLocation is file url)
<bean id="propertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" ref="envConfigLocation" />
<property name="order" value="1"/>
</bean>
I found an answer to this question at: How to redirect all logs from hibernate and spring to log4j2?
Basically log4j2 doesn't work with Hibernate so you have to use log4j. But you still use your log4j2 configuration. You need the following dependencies and then the magic happens in the background.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<!--HIBERNATE LOGGER (log4j)-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
It is possible to redirect calls to the log4j-1.x API to the log4j-2.0 implementation. The FAQ about which jars to include explains how to do this. You probably need to remove the old log4j-1.x jar from the classpath when you do this.
I have a very strange problem with Apache ActiveMQ with Camel - I tried the examples with javascript and groovy, but they both produce error "Failed to install route: Failed to create route... because of No language could be found for: groovy"
The groovy example I use is
<route>
<from uri="queue:foo"/>
<filter>
<groovy>request.lineItems.any { i -> i.value > 100 }</groovy>
<to uri="queue:bar"/>
</filter>
</route>
The same issue goes for JavaScript. The only scripting that works is "Simple" - the internal Camel scripting language. Please give me advice how to fix this. I am using ActiveMQ 5.2.4 with the integrated Apache Camel 2.4.0.
Yeah you need to add the JARs from camel-script and the scripting language of choice, eg for groovy you need the groovy JAR. If you run AMQ you should drop them in the lib folder.
Do you have a dependency on camel-script fulfilled?
For instance in maven this would be declared as:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-script</artifactId>
<version>2.6.0</version>
</dependency>
In your <dependencies> declaration.
I added artifact camel-groovy because camel-script didn't work for me.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-groovy</artifactId>
<version>2.23.0</version>
</dependency>