Grails-Plugin-Consortium / grails-cxf-client

Easy cxf client for grails
http://grails.org/plugin/cxf-client
27 stars 30 forks source link

cxf-client wsdl2java doesn't generate PortType class #31

Closed PatrickHuetter closed 11 years ago

PatrickHuetter commented 11 years ago

I added a new cxf-client to my configuration. After that i have a problem with the clientInterface. It doesn't get generated by grails wsdl2java. (There is no error message thrown).

After starting my grails application i get:

| Running Grails application
Web service client paymentClient cannot be created before setting the clientInterface=[:]       and serviceEndpointAddress=https://pal-test.adyen.com/pal/servlet/soap/Payment   properties
| Error 2013-03-27 15:43:52,921 [localhost-startStop-1] ERROR CxfClientGrailsPlugin  - Web service client paymentClient cannot be created before setting the clientInterface=[:] and serviceEndpointAddress=https://pal-test.adyen.com/pal/servlet/soap/Payment properties
| Error 2013-03-27 15:44:04,952 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: Error creating bean with name 'paymentClient': Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Class' for property 'clientInterface'; nested exception is java.lang.IllegalArgumentException: Could not load class []!
Message: Error creating bean with name 'paymentClient': Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Class' for property 'clientInterface'; nested exception is java.lang.IllegalArgumentException: Could not load class []!
   Line | Method
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   138 | run      in java.util.concurrent.FutureTask
|   895 | runTask  in java.util.concurrent.ThreadPoolExecutor$Worker
|   918 | run      in     ''
^   680 | run . .  in java.lang.Thread

Caused by TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Class' for property 'clientInterface'; nested exception is java.lang.IllegalArgumentException: Could not load class []!
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   138 | run      in java.util.concurrent.FutureTask
|   895 | runTask  in java.util.concurrent.ThreadPoolExecutor$Worker
|   918 | run      in     ''
^   680 | run . .  in java.lang.Thread

    Caused by IllegalArgumentException: Could not load class []!
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   138 | run      in java.util.concurrent.FutureTask
|   895 | runTask  in java.util.concurrent.ThreadPoolExecutor$Worker
|   918 | run      in     ''
^   680 | run . .  in java.lang.Thread

My configuration looks like:

cxf {
    client {
        recurringClient {
            wsdl = "https://pal-test.adyen.com/pal/Recurring.wsdl"
            bindingFile = "src/wsdl/recurringBindings.xml"
            requestContext = [
                (javax.xml.ws.BindingProvider.USERNAME_PROPERTY): "ws@Company.Name",
                (javax.xml.ws.BindingProvider.PASSWORD_PROPERTY): "password"]
            clientInterface = com.adyen.services.recurring.RecurringPortType
            serviceEndpointAddress = "https://pal-test.adyen.com/pal/servlet/soap/Recurring"
        }

        paymentClient {
            wsdl = "https://pal-test.adyen.com/pal/Payment.wsdl"
            bindingFile = "src/wsdl/recurringBindings.xml"
            requestContext = [
                (javax.xml.ws.BindingProvider.USERNAME_PROPERTY): "ws@Company.Name",
                (javax.xml.ws.BindingProvider.PASSWORD_PROPERTY): "password"]
            //          clientInterface =
            serviceEndpointAddress = "https://pal-test.adyen.com/pal/servlet/soap/Payment"
        }
    }

Setting the clientInterface in paymentClient to com.adyen.payment.client.PaymentPortType doesn't work because there is no such class in the generated wsdl src folder. I found the package name and class in the adyen demo project: https://github.com/adyenpayments/java/blob/master/java-adyen-client/src/com/adyen/demo/DemoAuth.java

Does somebody know a solution? Why doesn't cxf-client (wsdl2java) generate the PortType class? I think i've found it in the wsdls xml.

ctoestreich commented 11 years ago

I ran wsdl2java on the command line and had to add -autoNameResoultion to make it work. Check the plugin docs on how to add that for the client and try running again in grails. You will have to provide the clientInterface again for it to work at runtime.

wsdlArgs = ['-autoNameResolution']
ctoestreich commented 11 years ago

In the end you should have something like this

cxf {
    client {
        recurringClient {
            wsdl = "https://pal-test.adyen.com/pal/Recurring.wsdl"
            bindingFile = "src/wsdl/recurringBindings.xml"
            requestContext = [
                (javax.xml.ws.BindingProvider.USERNAME_PROPERTY): "ws@Company.Name",
                (javax.xml.ws.BindingProvider.PASSWORD_PROPERTY): "password"]
            clientInterface = com.adyen.services.recurring.RecurringPortType
            serviceEndpointAddress = "https://pal-test.adyen.com/pal/servlet/soap/Recurring"
        }

        paymentClient {
            wsdl = "https://pal-test.adyen.com/pal/Payment.wsdl"
            bindingFile = "src/wsdl/recurringBindings.xml"
            requestContext = [
                (javax.xml.ws.BindingProvider.USERNAME_PROPERTY): "ws@Company.Name",
                (javax.xml.ws.BindingProvider.PASSWORD_PROPERTY): "password"]
            clientInterface = com.adyen.services.payment.PaymentPortType
            serviceEndpointAddress = "https://pal-test.adyen.com/pal/servlet/soap/Payment"
            wsdlArgs = ['-autoNameResolution']
        }
    }
PatrickHuetter commented 11 years ago

This didn't work for me in grails directly. Using wsdl2java on the console worked, i could generate the classes. But now i can't start my grails app because of unmappable characters. Bildschirmfoto 2013-03-27 um 22 32 48 Using find and replace in eclipse helped out to replace the characters. But after that i've another problem: The attribute required is undefined for the annotation type XmlElementRef. Bildschirmfoto 2013-03-27 um 22 34 19

Do you know a solution?

ctoestreich commented 11 years ago

Generated just fine for me. I changed the clientInterface to a string and that seemed to clear it up. Get latest on my test project.

ctoestreich commented 11 years ago

The objects above weren't created with a bindings file. You need to use the bindings file I have provided on your clients so it will generate concrete data types not the JAXBElement types.

PatrickHuetter commented 11 years ago

After cloning your test project i get the following error message in my project: Bildschirmfoto 2013-03-28 um 01 15 23

ctoestreich commented 11 years ago

What java version?

PatrickHuetter commented 11 years ago

java version "1.6.0_41" Java(TM) SE Runtime Environment (build 1.6.0_41-b02-445-11M4107) Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01-445, mixed mode) (Mac OS X 10.7.5)

Should i install Java 7?

ctoestreich commented 11 years ago

Take that back. Clean and compile caused same issue. Let me check it out.

ctoestreich commented 11 years ago

Looks like it needs

wsdlArgs = ['-autoNameResolution','-frontend','jaxws21']
ctoestreich commented 11 years ago

checked in new project files.

PatrickHuetter commented 11 years ago

Seems to compile now! :-) Could you please push the applicationContext.xml too?

| Error 2013-03-28 15:37:17,265 [localhost-startStop-1] ERROR [localhost].[/cxf-client-hutter]  - Exception sending context initialized event to listener instance of class org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener
Message: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
   Line | Method
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   138 | run      in java.util.concurrent.FutureTask
|   895 | runTask  in java.util.concurrent.ThreadPoolExecutor$Worker
|   918 | run      in     ''
^   680 | run . .  in java.lang.Thread

Caused by FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
->> 303 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   138 | run      in java.util.concurrent.FutureTask
|   895 | runTask  in java.util.concurrent.ThreadPoolExecutor$Worker
|   918 | run      in     ''
^   680 | run . .  in java.lang.Thread
ctoestreich commented 11 years ago

done

PatrickHuetter commented 11 years ago

Thank you very much! Everything works now! :-) I get the following message on console when i send a request: GRAILS-7799: Subtype 'com.sun.proxy.$Proxy73' of reloadable type com.adyen.services.payment.PaymentPortType is not reloadable: may not see changes reloaded in this hierarchy (please comment on that jira)

That doesn't affect the functionality (everything works and requests are sent).

ctoestreich commented 11 years ago

I am not sure where that message is coming from, but I would guess that it may stem from my watched resources and the fact that the clients can not be reloaded dynamically like grails services due to how I am wiring them. Since the ws factory bean wires up clients based on interfaces, if you try and recreate the port from wsdl2java you will have to stop/start your server. No biggie.