Reputation: 2585
I want to migrate a Spring application to Spring Boot. The original application is composed out of several maven modules, I want to reuse one of the existing modules. The module that I want to reuse is a generated cxf web service client. It is linked in the application's pom.xml
like this:
<dependency>
<groupId>generated.package</groupId>
<artifactId>cxf-service-adapter</artifactId>
<version>1.0</version>
</dependency>
The generated GenCxfService
interface within that module looks like this
@WebService(targetNamespace = "https://the-domain/the-service/", name = "genCxfService")
@XmlSeeAlso({ObjectFactory.class})
public interface GenCxfService {
// the anotated web service methods
// ....
}
I need the web service client interface GenCxfService
to be managed by Spring Boot so that I can pass it into an spring security AuthenticationProvider
.
Well, I thought it wouldn't be a big deal. I took the compiled cxf-service-adapter-1.0.jar
from the module, placed it into an own in-project repository and tried to setup the java configuration to @autowire
the bean. First I tried it like this:
import generated.package.GenCxfService;
...
@ComponentScan({"generated.package.*","my.package.*"})
...
@Bean
public MyAuthenticationProvider myAuthenticationProvider() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("https://the-domain/the-service/");
factory.setServiceClass(GenCxfService.class);
GenCxfService genCxfService = (GenCxfService) factory.create();
return new my.package.authentication.MyAuthenticationProvider(userDAO, genCxfService);
}
This gives me the following exception during runtime:
javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: https://the-domain/the-service/the-wsdl.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy126.validateMyUser(Unknown Source)
at my.package.authentication.MyAuthenticationProvider.authenticate(MyAuthenticationProvider.java:47)
I thought I would simply have a faulty java configuration and tried to do a workaround by reusing the exiting xml configuration from the original project module, using
@ImportResource({"classpath:web-service.xml"})
with xml file:
<jaxws:client id="genCxfService"
serviceClass="generated.package.GenCxfService"
address="https://the-domain/the-service/the-wsdl.asmx">
</jaxws:client>
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="logInbound" />
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="logInbound" />
</cxf:inFaultInterceptors>
</cxf:bus>
This is how a client is configured in the cxf documentation (Configuring a Spring Client Option 1). Nevertheless, I still get the same error.
What am I doing wrong?
Adding cxf-rt-transports-http to the pom did the trick:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
Could anybody explain why the absence of the library doesn't throw exceptions during start-up but during runtime?
Thanks in advance.
Upvotes: 0
Views: 1594
Reputation: 756
Spring boot will find the classes at runtime so you don't have to depend on a specific library, it will use reflection to look up the classes that fulfill the interfaces it needs to allow easy swapping of implementations.
The classes are also lazily initiated or looked up so that's why it happens only when a request is sent through and not when it's started.
Upvotes: 1