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.
Related
I have to write a small project, which is not runnable by itself, but it is used by some other ("main") project as dependency to do some database operations and some simple business logic. So there will be no actual main class in my project, only some API, which will be used by the main project. Now I was wondering, if it is possible, to use Spring Boot with Spring Data JPA in my small project for Database operations. So there will be no #SpringBootApplication annotated class. (And the main project is also not a Spring Boot application)
So I actually modified my pom.xml by adding this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
(...)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Also I added an application.properties file in resources folder:
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=false
And finally, I added a simple config file:
#Configuration
#ComponentScan
#EnableJpaRepositories("package-of-the-JPA-repositories")
//#EnableAutoConfiguration
#EntityScan("package-of-the-entities")
#PropertySource("classpath:/application.properties")
public class SpringConfig {
}
Well, this configuration done, I tried to run the main project, but it sais, it cannot find the entityManagerFactory bean. As I understood, Spring Boot should generate this bean from the specified properties. So my question would be: 1) Is the thing I am tring to do generally possible? Means, is it possible to use Spring Boot without having an #SpringBootApplication annotated class? Or should I rather get rid of Spring Boot and use only Spring Data and Hibernate? And if it is possible, what am I possibly doing wrong? Any ideas?
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
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>