Announcement Announcement Module
Collapse
No announcement yet.
WebServiceRef injection of CXF jax-ws client Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • WebServiceRef injection of CXF jax-ws client

    I am trying to have my jax-ws client (using Apache CXF) injected via the @WebServiceRef. I have gone through the following steps:

    1. Generated the stubs from the WSDL.
    2. Created the following <jaxws:client> entry in my applicationContext.xml on the Interface generated through the WSDL.
    3. Inserted an @WebServiceRef annotation to inject the web service.

    This isn't working and I am getting an exception saying that the Bean is not of the required type, and that it should be of type javax.xml.ws.Service. What am I doing wrong?

    The following is my code snippet.

    applicationContext.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:jaxws="http://cxf.apache.org/jaxws"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    
    	<import resource="classpath:META-INF/cxf/cxf.xml" />
    	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
        
        <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
        
        <jaxws:client id="myService" serviceClass="mt.com.go.springtest.MyService"
                      address="http://localhost:8080/MyService" name="myService"/>
    
      <bean class="example.MyClient" name="myClient" />    
                      
    </beans>
    MyClient.java
    Code:
    public class MyClient
    {
      @WebServiceRef
      MyService myService;
    
    ...
    Exception stacktrace:
    Code:
    Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'myService' must be of type [javax.xml.ws.Service], but was actually of type [$Proxy62]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    ...

  • #2
    1)At server side:

    Make sure that your service impl and SEI[interface for webservice] both have @WebServicre annotation.

    Assuming that MyService is an SEI and it has @WebService exposed

    its impl also should have:

    @WebService(endpointInterface = mt.com.go.springtest.MyService")

    2)At Client side:
    try to inject myService in MyClient also.

    Comment


    • #3
      WebServiceRef annotation

      I am not implementing the server, so it doesn't have anything to do with the server implementation. I just have a WSDL which I am processing into stubs on the client side to use.

      Injection without @WebServiceRef works OK. But that's the whole point. I do not want to manually inject it in every bean that needs the Web service stub and I do not want to insert stuff like @Autowire etc.

      I wish to use the @WebServiceRef annotation client side, so that any bean which refers to the web service client stub gets it through there. This would be fully JAX-WS and JEE compliant.

      The @WebServiceRef is advertised to work in Spring but I can't find a proper example anywhere and trial and error just got me to the above point.

      Comment


      • #4
        Are you using standalone client?If yes,then you can refer:
        You can refer to:http://java.sun.com/javaee/5/docs/tu...doc/bnayn.html
        Code:
            public class HelloClient {
            @WebServiceRef(wsdlLocation="http://localhost:8080/
                    helloservice/hello?wsdl")
            static HelloService service;
        
            public static void main(String[] args) {
                try {
                    HelloClient client = new HelloClient();
                    client.doTest(args);
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        I see wsdlLocation is missing in your code but thats just my guess that it can be an issue.
        IAnyway,I will try a sample using @WebServiceRef later.
        Last edited by spring2007; Jun 8th, 2010, 09:09 AM.

        Comment


        • #5
          I want to avoid that because I don't want to hardcode the URL of the WSDL in the annotation.

          I want it to pick it up from the <jaxws:client> configuration which will have everything; endpoint URL, WSDL Location URL (which afaik is optional), username, password etc.

          Comment


          • #6
            I've never used the @WebServiceRef stuff, but if you read the javadoc for it, it basically says that if you are injecting into a field that is the SEI, you have to specify the "value" attribute that points to the subclass of javax.xml.ws.Service. I don't know if the Spring processing even cares about the Service subclass, but the javadocs say it must be there. You might also want to specify the "type" attribute as well, just to be clear.

            Comment


            • #7
              Yep tried it too (both with the type and without the type, using both the WebServiceClient class implementing javax.xml.ws.WebService and the Interface). I get a similar error.

              Code:
              Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'myService' must be of type [mt.com.go.springtest.MyService_Service], but was actually of type [$Proxy62]
              	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:348)
              	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
              ...
              Is it my impression that this approach with the @WebServiceRef is not that common?
              It is mentioned in specs and J2EE tutorials, but not much more. The advantage to inject it pre-configured by the framework (Spring, Glassfish or whatever) isn't mentioned ever and I haven't found one example anywhere yet.

              Comment


              • #8
                @Resource works

                By the way, I just discovered that @Resource works cleanly, without any parameter.

                I wonder why @WebServiceRef doesn't work.

                Comment


                • #9
                  My experience with @Resource vs native Spring autowiring is that native Spring autowiring doesn't like abstract class based injections in stead of interface based injections even though the documentation states that it should work.

                  Comment


                  • #10
                    Another way to solve this?

                    I realize you had posted this a while ago but I came accross your post trying to solve the same problem. I think I have found a way to use the @WebServiceRef annotation like you may have wanted to do.

                    Now my client is a web application running inside JBoss with the JBossWS-CXF web service stack so it is possible it worked for me because something JBoss was doing and not CXF but I thought I'd offer.

                    What worked for me was to have a combination of the 'createdFromAPI' attribute and a different name of the <jaxws:client> bean.

                    Code:
                    <jaxws:client name="{http://billing.webagesolutions.com/}BillingManagerPort" createdFromAPI="true"
                    		serviceClass="com.webagesolutions.billing.client.BillingManager">
                    The critical thing here is the 'name' attribute is the port name of the endpoint being created in the form "{http://service.target.namespace}PortName". This is from the description of the 'createdFromAPI' attribute in the CXF JAXWS configuration page:
                    http://cxf.apache.org/docs/jax-ws-configuration.html

                    Using this it was possible for me to use just the following to get a service reference:

                    Code:
                    @WebServiceRef
                    BillingManagerService bms;
                    (later in the code)

                    Code:
                    BillingManager service = bms.getBillingManagerPort();
                    Now like I say, because I'm running in a client that is in a JBoss environment it is possible that the thing that does the @WebServiceRef construction is JBoss since in an application server this annotation is supposed to refer to a "managed" service reference. Without a Java EE server environment you might not get this behavior.

                    Comment

                    Working...
                    X