Actually, in the end, I did switch back to jaxb and option 2 to change Foo to something else. The aegis binding was having some other issues with multiple namespaces in the wsdl files it generated I need to distill into a test case (It works with more or less the same structure in XFire though)

I'm still having an issue with combining interfaces using CXF though that's problematic on the client side.

If I do the CoreService, AppService, and PublicService as defined below, XFire could take PublicService and a JDK proxy object and construct all the correct methods. On the server, I can create an abstract fake class and pass it as the implementorClass which seems to work:
@WebService(endpointInterface="package.PublicService", ...)
public abstract class PublicServiceFake implements PublicService { }

On the client, if I try to create a client based on PublicService, it finds and can invoke the methods on CoreService, but throws an error it can't find information on methodOne when I try to invoke it. (Sorry, don't have the stack trace in front of me right now.. I can recreate it sometime later today) All the methods on all interfaces are annotated with @WebMethod and @WebParam annotations.

If I do "AppService extends CoreService" and then configure an AppService, I get the same result. If I then do "PublicService extends AppService" (instead of "PublicService extends CoreService, AppService), it works on the client but seems clunky that it can't properly find all the WebMethod functions on the multiple direct child interface case. In some cases, we have PublicService extending 3 or more child interfaces depending on the app, but it only finds methods in the first child interface.

This is in both 2.0.1 and yesterday's 2.1 snapshot.

--Joe

On Aug 31, 2007, at 1:00 PM, Daniel Kulp wrote:


Other options would be:

1) add @WebMethod(name = "fooOperation") to the operation (to generate
the wrapper element with that name

2) change/remove the @XmlRootElement annotation in the "Foo" class to
make it not generate a Foo element.   (may need to combine with 3)

3) add @WebResult annotation with a name set to "FooResult" or something
to give it a unique name.

Dan


On Thursday 30 August 2007, Joe Sunday wrote:
As an update to this after spending some more time trying to unwind
it...

It appears the problem was actually due to a method in one of my
interfaces:
Foo foo(...)

JAXB would collide the Foo type and the foo method. Setting up an
Aegis binding instead seems to have cleared it up.

--Joe

On Aug 30, 2007, at 2:44 AM, Joe Sunday wrote:
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.createWr
ap pedMessageSchema(ReflectionServiceFactoryBean.java:660)
        at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createWr
ap pedSchema(ReflectionServiceFactoryBean.java:511)
        at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initiali
ze WrappedSchema(ReflectionServiceFactoryBean.java:430)
        at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildSer
vi ceFromClass(ReflectionServiceFactoryBean.java:240)
        at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initiali
ze ServiceModel(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



--
J. Daniel Kulp
Principal Engineer
IONA
P: 781-902-8727    C: 508-380-7194
[EMAIL PROTECTED]
http://www.dankulp.com/blog

Reply via email to