Spring 3.2.3.Release and Junit4 4.11
I created a web-application Spring MVC REST project. This is the project which has the controllers which wrap around the Service and the Domain entities. The DAO and Services from the other project are all unit tested and working fine, so that is not the problem. The DAO's and Services have come in from a compiled jar file.
I am using maven, so I do have Spring-web, Spring-webmvc, Spring Core, Spring-Beans, Spring-test ... Spring-test is the 3.2.3.Release version, not the separate GitHub version.
I have spent 2 days looking at the Internet, Google, and StackOverflow, and the Spring Forums for a definitive answer, and yet I can't get the exact answer that I need, so I need another set of eyes to look at my files to see if something is basically wrong.
The problem is my unit test does not work, it's very minimal, but comes up with a huge error, and I can't even execute any tests at all. So, let me start my listing my code and xml files.
If anyone can look at the error and look at the code, if something is off, can you please let me know. And in the meantime I will continue to do more research on my own.
I'll start with the error from the console:
(main)2013-07-30 13:33:56,336 INFO [org.hibernate.impl.SessionFactoryImpl] - <closing>
(main)2013-07-30 13:33:56,336 ERROR [org.springframework.test.context.TestContextManager] - <Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#6c07588c] to prepare test instance [com.tom.rest.controller.invoice.InvoiceControllerTests#564686bc]>
(main)java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'invoiceControllerTests': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext com.tom.rest.controller.invoice.InvoiceControllerTests.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
... 24 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.context.WebApplicationContext com.tom.rest.controller.invoice.InvoiceControllerTests.wac; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 39 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 41 more
applicationContext.xml because of the dependency on the dao and service jar, these imports come from that project.
<import resource="classpath:project-dao.xml"/>
<import resource="classpath:project-engines.xml"/>
<import resource="classpath:project-infrastructure.xml"/>
<import resource="classpath:project-interface.xml"/>
<import resource="classpath:project-service.xml"/>
<import resource="classpath:project-transactions.xml"/>
<import resource="classpath:project-ui.xml"/>
<import resource="classpath:project-webservices.xml" />
<context:component-scan base-package="com.tom.viper" />
<context:annotation-config />
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="invoiceControllerTests" class="com.tom.rest.controller.invoice.InvoiceControllerTests" />
springmvc-servlet.xml
<beans>
<context:component-scan base-package="com.tom.viper, com.tom.cobra" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="jsonHttpMessageConverter" />
</list>
</property>
</bean>
</beans>
web.xml
<web-app>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext.xml
/WEB-INF/classes/springmvc-servlet.xml
classpath:project-dao.xml
classpath:project-engines.xml
classpath:project-infrastructure.xml
classpath:project-interface.xml
classpath:project-service.xml
classpath:project-transactions.xml
classpath:project-ui.xml
classpath:project-webservices.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Servlets -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jUnitHostImpl</servlet-name>
<servlet-class>com.google.gwt.junit.server.JUnitHostImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jUnitHostImpl</servlet-name>
<url-pattern>/RevenueManager/junithost/*</url-pattern>
</servlet-mapping>
<!-- Servlets -->
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
And now the controller tests:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations =
{
"/applicationContext.xml",
"/springmvc-servlet.xml",
"classpath:project-infrastructure.xml",
"classpath:project-dao.xml",
"classpath:project-service.xml" })
public class InvoiceControllerTests
{
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup()
{
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
public void getInvoices()
{
assertEquals(true, true);
}
}
Remove
<bean id="invoiceControllerTests" class="com.tom.rest.controller.invoice.InvoiceControllerTests" />
in your applicationContext.xml.
you can make the InvoiceControllerTest implement ApplicationContextAware and grab the instance of applicationContext from the implementation of the lifecycle method.
Alternatively, you can Autowire specific controller instance that u want to test in ur test class and do a standalone setup like so,
this.mockMvc = MockMvcBuilders.standaloneSetup(this.invoiceController).build();
I came to a new company that had an existing Spring DAO and Services layer created and full unit tested. They use Ivy to handle dependencies and Ant build.xml files to handle the builds. I presumed that when the JAR was created, that this would be a self-contained file (encapsulated) with all the config files and necessary jar files. When I cracked open the JAR file, I was horrified that there was no config files or jars, it was simply the Java code from the project itself. That is why there was no Spring config files.
In my new maven project, it was asking me for all the jars that were missing from the previous project, so I just decided to create a new Maven Spring DAO/Service project and bring all the code over.
So to update:
In this new Maven project for DAO's and Services, I have the Spring config files under; src/main/resources/spring
and when this new JAR compiles, the new spring config files are at:
WEB-INF/classes/spring
So, in my Spring Web MVC project, here is my applicationContext.xml now:
<import resource="classpath*:projct-dao.xml"/>
<import resource="classpath*:projct-engines.xml"/>
<import resource="classpath*:project-infrastructure.xml"/>
<import resource="classpath*:project-interface.xml"/>
<import resource="classpath*:projct-service.xml"/>
<import resource="classpath*:projct-transactions.xml"/>
<import resource="classpath*:project-ui.xml"/>
<import resource="classpath*project-webservices.xml" />
and here is part of the web.xml that handles the spring context files:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext.xml
/WEB-INF/viper-servlet.xml
classpath*:project-dao.xml
classpath*:project-engines.xml
classpath*:project-infrastructure.xml
classpath*:poject-interface.xml
classpath*:project-service.xml
classpath*:project-transactions.xml
classpath*:projct-ui.xml
classpath*:project-webservices.xml
</param-value>
</context-param>
Adding the wildcard (*) to the end of the classpath made it find the missing spring context files. This solves the problem with my web-app starting ... I hope this helps someone else.
Related
I'm implementing a web service using camel cxf to be deployed in Karaf.
I'm using the pax web that comes with karaf. I'm using the cxf codegen plugin in pom to do wsdl to java.
I'm defining the cxf uri and the routes in the RouteBuilder Java DSL. The blueprint.xml only has some beans and ref to the RouteBuilder.
final String cxfUri =
String.format("cxf:%s?serviceClass=%s&wsdlURL=wsdl/Event.wsdl",
"/Event.jws", com.example.EventPortType.class.getCanonicalName());
I have setup ssl with the pax-web(jetty.xml). If i send the WSSE security headers with username and password, it generates a MustUnderstand soap fault.
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-LdZa8aaGdy7mWQWXLp_zpbfg">
<wsse:Username>xxx</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxx</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
The input request cannot be changed.
I get this exception.
<soap:Fault>
<faultcode>soap:MustUnderstand</faultcode>
<faultstring>MustUnderstand headers: [{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood.</faultstring>
</soap:Fault>
How can i secure the cxf endpoint to authenticate the request?
Thank you.
you need to add a WSS4J interceptors to the exposed CXF service. You can provide your own PasswordCallback for the user validation, but I prefer to leverage the native JAAS. This is a blueprint example requiring the UsernameToken with any Karaf user (this is for exposing a camel-cxf routes, however the same principle applies to the pure CXF implementation). If you prefer Java based Camel route builders, you may add the interceptor beans to the context registry to use them. But - the blueprint (or spring config) allows you to more fine-grained control than simple endpoint parameters.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd http://camel.apache.org/schema/blueprint
http://camel.apache.org/schema/blueprint/camel-blueprint.xsd http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0
http://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/cxf/camel-cxf-2.7.5.xsd">
<bean id="authenticationInterceptor" class="org.apache.cxf.interceptor.security.JAASLoginInterceptor">
<property name="contextName" value="karaf"/>
<property name="roleClassifier" value="RolePrincipal"/>
<property name="roleClassifierType" value="classname"/>
</bean>
<bean id="wsSecInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<argument>
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordText"/>
</map>
</argument>
</bean>
<!-- ================ Apache Camel impl ======================= -->
<camelcxf:cxfEndpoint id="testService2"
address="/api/2.0/external/TestService"
xmlns:apogado="http://test.ws.apogado.com/v1_0/ws"
endpointName="apogado:AddressServicePort"
serviceName="apogado:AddressService"
wsdlURL="classpath:/xsd/ws/TestService.wsdl"
>
<camelcxf:properties>
<entry key="dataFormat" value="PAYLOAD" />
<entry key="ws-security.ut.no-callbacks" value="true"/>
<entry key="ws-security.validate.token" value="false"/>
</camelcxf:properties>
<camelcxf:inInterceptors>
<ref component-id="wsSecInterceptor" />
<ref component-id="authenticationInterceptor"/>
</camelcxf:inInterceptors>
<camelcxf:features>
</camelcxf:features>
</camelcxf:cxfEndpoint>
<camelContext xmlns="http://camel.apache.org/schema/blueprint" id="testWsCtx" trace="true">
<!-- your service implementation -->
<route>
<from uri="testService2" />
<to uri="..." />
<route>
</camelContext>
</blueprint>
I am trying to evaluate Spring Integration specially interested in exposing a simple POJO based service into a SOAP based webservice via service activator. Currently I am stuck & have issue generating dynamic wsdl. The WSDL is not loaded & browser shows 404 error.
I try to access with the following url on my local
http://localhost:8080/ws-inbound-gateway/echoService
http://localhost:8080/ws-inbound-gateway/echoService/echoService.wsdl
Below is the configuration
inbound-gateway-config.xml
<int:channel id="inbound" />
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.manish.schema.generated" />
</bean>
<int-ws:inbound-gateway id="empServiceGateway"
request-channel="inbound" marshaller="marshaller"
unmarshaller="marshaller" />
<int:service-activator input-channel="inbound"
requires-reply="true" ref="employeeServiceActivator" method="getEmployeeDetails">
</int:service-activator>
<bean id="employeeServiceActivator"
class="org.springframework.integration.samples.ws.EmployeeServiceResponder" />
<bean id="employeeService" class="com.manish.service.EmployeeService" />
EmployeeService is just a pojo class while EmployeeServiceResponder is a service activator that invokes method on a service class.
For dynamic wsdl generation
spring-ws-config.xml
<import resource="classpath:/META-INF/spring/integration/inbound-gateway-config.xml" />
<sws:dynamic-wsdl id="echoService" portTypeName="empServiceGateway" locationUri="/echoService" targetNamespace="http://manish.niyati.com/echo">
<sws:xsd location="/WEB-INF/echo.xsd"/>
</sws:dynamic-wsdl>
<bean
class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
<property name="defaultEndpoint" ref="empServiceGateway"></property>
</bean>
web.xml
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-ws-config.xml</param-value>
</init-param>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/echoService</url-pattern>
</servlet-mapping>
Kindly let me know what else is missing in order to make this service accessible as web-service via SI.
Also when I try to access the service from using WebService template I get the SOAPFAULT
02:18:59.436 INFO [main][org.springframework.ws.soap.saaj.SaajSoapMessageFactory] Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
02:18:59.437 DEBUG [main][org.springframework.ws.soap.saaj.SaajSoapMessageFactory] Using MessageFactory class [com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl]
02:18:59.484 DEBUG [main][org.springframework.ws.client.core.WebServiceTemplate] Opening [org.springframework.ws.transport.http.HttpUrlConnection#249fa95c] to [http://localhost:8080/ws-inbound-gateway/echoService]
02:18:59.519 TRACE [main][org.springframework.ws.soap.saaj.support.SaajUtils] SOAPElement [com.sun.xml.internal.messaging.saaj.soap.ver1_1.Envelope1_1Impl] implements SAAJ 1.3
02:18:59.535 TRACE [main][org.springframework.ws.soap.saaj.support.SaajUtils] SOAPElement [com.sun.xml.internal.messaging.saaj.soap.ver1_1.Body1_1Impl] implements SAAJ 1.3
02:18:59.562 TRACE [main][org.springframework.ws.client.MessageTracing.sent] Sent request [<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ed:employeeRequest xmlns:ed="http://manish.niyati.com/echo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ed:empid>100</ed:empid> </ed:employeeRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>]
02:18:59.604 TRACE [main][org.springframework.ws.client.MessageTracing.received] Received response [<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring xml:lang="en">**java.lang.NullPointerException**</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>] for request [<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ed:employeeRequest xmlns:ed="http://manish.niyati.com/echo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ed:empid>100</ed:empid> </ed:employeeRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>]
02:18:59.605 DEBUG [main][org.springframework.ws.client.core.WebServiceTemplate] Received Fault message for request [SaajSoapMessage {http://manish.niyati.com/echo}employeeRequest]
02:18:59.607 TRACE [main][org.springframework.ws.soap.saaj.support.SaajUtils] SOAPElement [com.sun.xml.internal.messaging.saaj.soap.ver1_1.Fault1_1Impl] implements SAAJ 1.3
Thanks in Advance
-MS
To get the WSDL, change the web.xml url-pattern to <url-pattern>/*</url-pattern>.
and the URL is http://localhost:8080/ws-inbound-gateway/echoService.wsdl.
Everything else looks good.
Regarding the WebServiceTemplateQuestion, what are you sending? It looks like you are using the ws sample app, which uses a WebServiceTemplate...
#Test
public void testWebServiceRequestAndResponse() {
StringResult result = new StringResult();
Source payload = new StringSource(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<echoRequest xmlns=\"http://www.springframework.org/spring-ws/samples/echo\">hello</echoRequest>");
template.sendSourceAndReceiveToResult(WS_URI, payload, result);
logger.info("RESULT: " + result.toString());
assertThat(result.toString(), equalTo(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<echoResponse xmlns=\"http://www.springframework.org/spring-ws/samples/echo\">hello</echoResponse>"));
}
And that works just fine.
Looks like your NPE is on the server - take a look at the server logs to see what happened.
You are doing it in a much more complex way. With a simple configuration and using some basic annotations, you can develop a web service in a short time.
I have myself used Apache CXF for web service development and it is quite good for spring based configuration. You can also take a look at this blog. It has shown all the steps with figures to develop a web service with the generation of wsdl and a client to consume the web service.
I am developing a new web service. But I cannot seem to figure out the best way to set up the web service to deploy in jboss as 7.
As per the jboss documentation, here is the 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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>testService</servlet-name>
<servlet-class>com.sgb.testService.ws.web.TestService</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testService</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
As per the jboss docs, it also needs a jboss-cxf.xml for all the configurations for cxf and spring.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:wsa="http://cxf.apache.org/ws/addressing"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd ">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<!-- import spring application context configurations -->
<import resource="classpath:META-INF/spring/applicationContext-ws.xml" />
<jaxws:endpoint id="testService"
implementor="com.sgb.testService.ws.web.TestService"
address="/testService" >
<!--
address="http://localhost:8080/testService">
-->
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
<jaxws:invoker>
<bean class="org.jboss.wsf.stack.cxf.InvokerJSE" />
</jaxws:invoker>
</jaxws:endpoint>
And the spring configurations are defined in the ApplicationContext-ws.xml here.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties" />
<!--
import the common configurations from core sub-module
which contains the declarations for Datasource, EntityManagerFactory & PersistanceUnit
-->
<import resource="applicationContext-core.xml" />
<import resource="applicationContext-jpa.xml" />
<!-- setting up multiple packages to scan for components -->
<context:component-scan base-package="com.sgb.testService.ws.service" />
<!-- Declare the Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- declare transactions as annotation driven -->
<tx:annotation-driven
transaction-manager="transactionManager" />
Does the above look right?
Am I missing anything?
Specific Question:
For deploying a cxf based web service in jboss AS 7, where does the spring beans configuration (ApplicationContext-ws.xml above) need to be defined?
Can someone point me to a recent (2012) example or tutorial. Most of the examples I find online seem to be old and I cannot seem to find a proper tutorial in the jboss or spring websites...
Thank you.
-SGB
EDIT TO ADD:
The error message seems to indicate that while deploying the war file, jboss is attempting to publish the wsdl to JBOSS_HOME/standalone/data/wsdl/TestService.war, but is failing as it cannot find the schema (xsd file). This is a bit strange as bot the schema and wsdl is inside WEB-INF/wsdl/ directory.
where
JBOSS_HOME = C:\Program Files (x86)\Apache Software Foundation\jboss-as-7.1.1.Final\
ERROR MESSAGE:
15:56:09,146 INFO [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-4) Creating Service {http://www.sgb.com/Slm/ES
/TestServiceIdentifier}TestServiceIdentifier from WSDL: WEB-INF/wsdl/TestService.wsdl
15:56:09,238 INFO [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-4) Setting the server's publish address to be http://localhost:8080/eucl
id-ws
15:56:09,266 INFO [org.jboss.wsf.stack.cxf.deployment.WSDLFilePublisher] (MSC service thread 1-4) WSDL published to: JBOSS_HOME/standalone/data/wsdl/testService-ws.war /TestService.wsdl
15:56:09,270 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.deployment.unit."testService-ws.war".INSTA
LL: org.jboss.msc.service.StartException in service jboss.deployment.unit."testService-ws.war".INSTALL: Failed to process phase INSTALL of deployment "eucl
id-ws.war"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_33]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_33]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_33]
Caused by: java.lang.RuntimeException: Cannot publish wsdl to: JBOSS_HOME\standalone\data\
wsdl\testService-ws.war\TestService.wsdl
at org.jboss.wsf.stack.cxf.deployment.WSDLFilePublisher.publishWsdlFiles(WSDLFilePublisher.java:107)
at org.jboss.wsf.stack.cxf.deployment.EndpointImpl.publishContractToFilesystem(EndpointImpl.java:222)
at org.jboss.wsf.stack.cxf.deployment.EndpointImpl.doPublish(EndpointImpl.java:93)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:239)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:509)
at org.jboss.wsf.stack.cxf.configuration.NonSpringBusHolder.configure(NonSpringBusHolder.java:117)
at org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.startDeploymentBus(BusDeploymentAspect.java:113)
at org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.start(BusDeploymentAspect.java:66)
at org.jboss.as.webservices.deployers.AspectDeploymentProcessor.deploy(AspectDeploymentProcessor.java:74)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1
.Final]
... 5 more
Caused by: java.io.FileNotFoundException: JBOSS_HOME\standalone\data\wsdl\testService-ws.war\TestServiceIdentifier.xsd (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method) [rt.jar:1.6.0_33]
at java.io.FileInputStream.<init>(FileInputStream.java:120) [rt.jar:1.6.0_33]
at java.io.FileInputStream.<init>(FileInputStream.java:79) [rt.jar:1.6.0_33]
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70) [rt.jar:1.6.0_33]
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161) [rt.jar:1.6.0_33]
at java.net.URL.openStream(URL.java:1010) [rt.jar:1.6.0_33]
at org.jboss.ws.common.utils.AbstractWSDLFilePublisher.publishSchemaImports(AbstractWSDLFilePublisher.java:243)
at org.jboss.ws.common.utils.AbstractWSDLFilePublisher.publishSchemaImports(AbstractWSDLFilePublisher.java:250)
at org.jboss.ws.common.utils.AbstractWSDLFilePublisher.publishSchemaImports(AbstractWSDLFilePublisher.java:250)
at org.jboss.wsf.stack.cxf.deployment.WSDLFilePublisher.publishWsdlFiles(WSDLFilePublisher.java:94)
... 14 more
15:56:09,343 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS015870: Deploy of deployment "testService-ws.war" was rolled back with failure
message {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"testService-ws.war\".INSTALL" => "org.jboss.msc.service.StartException in service jbos
s.deployment.unit.\"testService-ws.war\".INSTALL: Failed to process phase INSTALL of deployment \"testService-ws.war\""}}
15:56:09,413 INFO [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015877: Stopped deployment testService-ws.war in 70ms
15:56:09,414 INFO [org.jboss.as.controller] (DeploymentScanner-threads - 2) JBAS014774: Service status report
JBAS014777: Services which failed to start: service jboss.deployment.unit."testService-ws.war".INSTALL: org.jboss.msc.service.StartException in serv
ice jboss.deployment.unit."testService-ws.war".INSTALL: Failed to process phase INSTALL of deployment "testService-ws.war"
15:56:09,421 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) {"JBAS014653: Composite operation failed and was rolled ba
ck. Steps that failed:" => {"Operation step-2" => {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"testService-ws.war\".INSTALL" => "org.jboss.m
sc.service.StartException in service jboss.deployment.unit.\"testService-ws.war\".INSTALL: Failed to process phase INSTALL of deployment \"testService-ws.war\""
}}}}
From the above, the root cause seem to be this:
Caused by: java.io.FileNotFoundException: JBOSS_HOME\standalone\data\wsdl\testService-ws.war\TestServiceIdentifier.xsd (The system cannot find the file specified)
It seems like it is able to find the WSDL, but not the corresponding xsd which it uses which is available in the same directory as WSDL file.
As per this https://issues.jboss.org/browse/JBWS-3532, it might be due to the space in the path of JBOSS_HOME directory. As per a comment by a Richard Opalka in the link above, it looks like it was fixed in a newer build too.
I downloaded the latest nightly of jboss and installed in c:\jboss\ and the problem dis-appeared.
I have web services developed using Spring+ApacheCXF and I need tod eploy them on JBoss AS7.
They are being deployed by CXFServlet properly.
But JBoss AS7 also deploying them by scanning #WebService annotations(as expected without Spring Injection).
How to disable scanning #WebService annotations in JBoss AS 7?
PS: I am deploying as a .war file.
PS PS:
My current cxf webservices are being deployed properly. But JBoss AS7 also trying to scan #WebService classes and deploying them also(without dependencies injected).I am looking for a way to turn of JBossAS7's scanning for #WebService classes.
This applies for Jboss 6 as well. I tried it on my Jboss 6.2.2.
Comment the following in standalone.xml
<!-- <extension module="org.jboss.as.webservices"/> -->
Then comment the below snippet in the same standalone.xml. Note if you are using different profile name or in domain mode you will have to do it at similar places.
<!--
<subsystem xmlns="urn:jboss:domain:webservices:1.2">
<modify-wsdl-address>true</modify-wsdl-address>
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
-->
I believe you will want to remove this from your standalone.xml
<extension module="org.jboss.as.webservices"/>
and
<subsystem xmlns="urn:jboss:domain:webservices:1.1">
<modify-wsdl-address>true</modify-wsdl-address>
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
</subsystem>
This is what I did to remove the jboss webservices so I could use something else. I'm still in the middle of testing this but it is no longer deploying the services. I assume I will just be able to use spring to deploy. Hope this helps.
I am using exclude-filter in my application context XML file to exclude web service components from Spring component scan.
<context:component-scan base-package="your.application.base.package">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="javax.jws.WebService" />
</context:component-scan>
At the same time I include them in component scan in CXF context XML.
I'm using JBoss EAP 6.1 and i solved the same problem excluding the subsystems jaxrs and webservices.
jboss-deployment-structure.xml
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="jaxrs" />
<subsystem name="webservices" />
</exclude-subsystems>
<exclusions>
<module name="javaee.api" />
<module name="org.apache.log4j" />
</exclusions>
<dependencies>
<module meta-inf="export" name="com.liferay.portal">
<imports>
<include path="META-INF" />
</imports>
</module>
<module name="javax.mail.api" />
<module name="org.jboss.modules" />
</dependencies>
</deployment>
</jboss-deployment-structure>
I have implemented a web services using JaxWS-Spring. I would like to log the XML being received. I have tried various attempts, among which to add the proper categories to my log4j.properties file and using interceptors. However I have always failed for one reason or another (logging seems to be ignored - adding interceptors to my application context gives other issues).
The following snippets from my project :
PS: I am using Spring 2.5.6
web.xml
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mapping to redirect all requests from 'FaxWebService' to jaxws-servlet. -->
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/FaxWebService</url-pattern>
</servlet-mapping>
applicationContext.xml
<!-- Bind the URL FaxWebService to our bean FaxWebService. -->
<wss:binding url="/FaxWebService">
<wss:service>
<ws:service bean="#faxWebService"/>
</wss:service>
</wss:binding>
<!-- Bean responsible of taking care of the webservice. -->
<bean id="faxWebService" class="com.connexo.icubeplus3.dispatcher.webservices.FaxWebService"
scope="singleton">
<property name="dummyMode" value="${fax.dummy.mode}"/>
</bean>
I doubt this has anything to do with Spring WS to be honest.
If you want to log the incoming messages in Spring WS, you want to raise the logging level for org.springframework.ws.client.MessageTracing.sent and org.springframework.ws.client.MessageTracing.received to TRACE. For example, in log4j config:
<logger name="org.springframework.ws.client.MessageTracing.sent">
<level value="TRACE" />
<appender-ref ref="stdout" />
</logger>
<logger name="org.springframework.ws.client.MessageTracing.received">
<level value="TRACE" />
<appender-ref ref="stdout" />
</logger>
You will have to write a handler to log it. There are various examples in the web, like http://docs.oracle.com/cd/E13222_01/wls/docs103/webserv_adv_rpc/handlers.html