I'm trying to migrate an existing framework from Xfire over to CXF
(2.0.1 and tonight's 2.1 snapshot), and I can't get it to play nice.
There's a core framework that exports a web service interface of a
few methods. We have an additional application that builds on top of
that with it's own interface:
@WebService(...)
public interface CoreService {
@WebMethod(...)
Foo foo(...)
}
@WebService(...)
public interface AppService {
@WebMethod
ServiceResult methodOne(...)
@WebMethod
ServiceResult methodTwo(...)
}
Then we aggregate them together with a new interface that we actually
want exported:
@WebService(name = "MyService", targetNamespace = "http://localhost/
Service")
public interface PublicService extends CoreService, AppService {
}
Actually implementing methodXXX is handled by a JDK proxy class
created by a factory in Spring that implements PublicService and the
InvocationHandler maps them back to the right implementation. There
is no actual Impl class to speak of.
If I setup my endpoint like this:
<jaxws:endpoint
id="helloWorld"
implementor="#publicServiceProxy"
address="/SnapManager" />
I get this during startup:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'helloWorld': Invocation of init method
failed; nested except
ion is java.lang.RuntimeException: Schema for namespace 'http://
localhost/Service' already contains type 'foo
Caused by:
java.lang.RuntimeException: Schema for namespace 'http://localhost/
Service' already contains type 'foo
at org.apache.ws.commons.schema.XmlSchema.addType
(XmlSchema.java:229)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createWrappe
dMessageSchema(ReflectionServiceFactoryBean.java:660)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createWrappe
dSchema(ReflectionServiceFactoryBean.java:511)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeWr
appedSchema(ReflectionServiceFactoryBean.java:430)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildService
FromClass(ReflectionServiceFactoryBean.java:240)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeSe
rviceModel(ReflectionServiceFactoryBean.java:264)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create
(ReflectionServiceFactoryBean.java:143)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create
(JaxWsServiceFactoryBean.java:89)
at
org.apache.cxf.frontend.AbstractEndpointFactory.createEndpoint
(AbstractEndpointFactory.java:82)
at org.apache.cxf.frontend.ServerFactoryBean.create
(ServerFactoryBean.java:107)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create
(JaxWsServerFactoryBean.java:147)
at org.apache.cxf.jaxws.EndpointImpl.getServer
(EndpointImpl.java:287)
at org.apache.cxf.jaxws.EndpointImpl.doPublish
(EndpointImpl.java:227)
at org.apache.cxf.jaxws.EndpointImpl.publish
(EndpointImpl.java:179)
at org.apache.cxf.jaxws.EndpointImpl.publish
(EndpointImpl.java:340)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
I tried giving it a class to find the annotations on as well (though
I didn't need this in XFire, it just read off the Interface correctly):
@WebService(endpointInterface = "com.myapp.PublicService")
public abstract class PublicServiceFake implements PublicService {
}
and pointing the endpoint to it in Spring:
implementorClass="com.myapp.SnapManagerServiceFake"
with the same result. If I remove the "implements PublicService"
part, it'll startup, but then the generated wsdl doesn't actually
have any methods in it.
In XFire, my config looked like this (publicServiceProxy:
<bean name="xfire.annotationServiceFactory"
class="org.codehaus.xfire.annotations.AnnotationServiceFactory">
<constructor-arg index="0">
<bean
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />
</constructor-arg>
<constructor-arg index="1" ref="xfire.transportManager" />
</bean>
<bean name="myService"
class="org.codehaus.xfire.spring.remoting.XFireExporter">
<property name="serviceBean" ref="publicServiceProxy" />
<property name="serviceInterface"
value="com.myapp.PublicService" />
<property name="serviceFactory"
ref="xfire.annotationServiceFactory"/>
<property name="xfire" ref="xfire"/>
<property name="properties"> <!-- This property is needed to
allow eclipse tools to properly validate the WSDL file -->
<map>
<entry>
<key>
<value>wsdlBuilder.generateImports</value>
</key>
<value>true</value>
</entry>
</map>
</property>
</bean>
--Joe