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>
Related
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.
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
The stack I am using at the moment is:
log4j2 rc1
spring 3.2 core and web
tomcat 7.0.47
java 1.6.0_45
Windows 7
I don't have the ability to alter the tomcat version or java version and I would prefer not to alter the log4j version and spring version.
Essentially, when I undeploy my webapp I receieve a SEVERE warning saying:
SEVERE: The web application [/MyApp] appears to have started a thread named
[AsyncAppender-AsyncFile] but has failed to stop it. This is very likely to
create a memory leak
I can confirm that it does create a memory leak and this is what I am trying to fix.
So far I have attempted to create a custom ServletContextListener which contains the following code:
#Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Shutting down logger");
try {
((Log4jWebSupport) event.getServletContext().getAttribute(
Log4jWebSupport.SUPPORT_ATTRIBUTE)).clearLoggerContext();
((LifeCycle) LogManager.getContext()).stop();
} catch (Exception e) {
}
}
None of these two lines seems to fix the problem, however I can confirm that this code is being executed due to my sysout statement appearing in the tomcat console.
I am using log4j2 through an interceptor which I am setting up using Spring
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<ref bean="LoggingInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<bean id="LoggingInterceptor" class="MyLoggerClass">
The interceptor works correctly and the logs appear where I expect them to. My implementation of the logger is:
private static Logger log = LogManager.getLogger("MetricLogger");
public void log(LogPayload payload) {
if(payload != null){
log.info(payload.get());
}
}
Where LogPayload.get() returns a String.
As I am using the logging facility across multiple webapps I have created a separate jar file containing this and the classes recording the measurements. I have included this using maven and I compile it into the final war file I deploy to tomcat. This war file is included on a per app basis and is not included in the global tomcat/lib folder.
Does anyone have any insight as to why I get my memory leak issue and what the possible solutions are to fixing this?
Many thanks for your help and please let me know if you need further information.
The solution to this that I have so far found is that I need to include the following snippet in the web.xml.
<listener>
<listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
This is specific to servlet spec 2.5. This seems to resolve the memory leak issue.
In case you are facing this issue recently you should note the following:
If you are using servlet 3.0+ and tomcat > 7.0.43 or Tomcat 8 there are no configuration needed, you just have to provide the correct maven dependencies to make log4j2 aware of running in a webcontainer like the following (in addition we use slf4j):
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.0</version>
</dependency>
Since in our case the log4j-web artifact was missing we faced the same warning which said "... started a thread named [AsyncAppender-AsyncFile] but has failed to stop it ..."
After providing the mentioned dependencies the warning is gone.
you can read more about requirements here
Adding the below snippet worked for me to get rid of memory leak due to Async-Appender threads not getting shut down even after the application shutdown.
Thank you #kipper_t.
<listener>
<listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
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 am building a Spring MVC application and deploying to Tomcat. When I try to use the #Valid syntax, I get a compilation error:
Valid cannot be resolved to a type.
I am using Eclipse Java EE IDE for Web Developers (Helios SR2).
I have hibernate-validator.jar in my classpath, as the Spring documentation indicates, but I don't see javax.validation.* anywhere in my references.
Any help would be appreciated.
add
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
to your context and you have to have javax.validation.* classes on classpath
search for javax.validation in maven repositories or use following if you use Maven:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>com.springsource.javax.validation</artifactId>
<version>1.0.0.GA</version>
</dependency>