Grails-Plugin-Consortium / grails-cxf-client

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

Problems with cxf-client and adyen wsdl: Could not create web service client for interface #33

Open PatrickHuetter opened 11 years ago

PatrickHuetter commented 11 years ago

I'm developing a grails plugin for payment with adyen.com (called: "adyenplugin"). This grails plugin has some services i use in my mainproject (called: "mainproject"). My grails version is 2.2.0 and cxf-client 1.5.3.

I created a binary plugin of the adyenplugin and placed the library (jar) into the mainprojects lib folder. I also added the cxf-client config i also have in adyenplugin to the mainprojects config. The generated java files from wsdl2java (generated via cxf-client plugin) are placed in the adyenplugin (also packed in the jar).

After starting the mainproject with "run-app" sometimes everything works good (also the payment part where the cxf-client is used) but often the app crashes and doesn't start. It's not only on my computer, it's on all the computers i've tested. Then i do some clean, and restart the app. Often it works then, but very often it doesn't work again.

This is the exception i get after starting the mainproject with "run-app": https://gist.github.com/PatrickHuetter/74dae3c2b92d219b62d5#file-gistfile1-sh

I also tested to copy the generated java files to the src/java folder of my mainproject, but same problem here.

My config (username and password edited):

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

        paymentClient {
            wsdl = "https://pal-test.adyen.com/pal/Payment.wsdl"
            wsdlArgs = [    
                '-autoNameResolution',
                '-frontend',
                'jaxws21'
            ]
            bindingFile = "src/wsdl/recurringBindings.xml"
            clientInterface = "com.adyen.services.payment.PaymentPortType"
            requestContext = [
                (javax.xml.ws.BindingProvider.USERNAME_PROPERTY): "ws@Company.Encircle360",
                (javax.xml.ws.BindingProvider.PASSWORD_PROPERTY): "mpasswd"]
            serviceEndpointAddress = "https://pal-test.adyen.com/pal/servlet/soap/Payment"
        }
    }

recurringBindings.xml:

<jaxb:bindings version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>

Do you know any solution for that? I can't work really efficiently if the application doesn't start always.

ctoestreich commented 11 years ago

The underlying issues appears to be:

Caused by ClassCastException: null ->> 2999 | cast in java.lang.Class


| 104 | getProxy in org.apache.cxf.binding.soap.SOAPBindingUtil | 195 | getSoapBody . . . . in '' | 401 | createSoapBody in '' | 255 | createSoapBinding . in org.apache.cxf.binding.soap.SoapBindingFactory | 197 | createBindingInfo in '' | 85 | createBindingInfo . in org.apache.cxf.binding.AbstractBaseBindingFactory | 340 | createBindingInfo in org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory | 258 | createEndpointInfo in '' | 143 | createEndpoint in '' | 90 | create . . . . . . in org.apache.cxf.frontend.ClientFactoryBean | 155 | create in org.apache.cxf.frontend.ClientProxyFactoryBean | 156 | create . . . . . . in org.apache.cxf.jaxws.JaxWsProxyFactoryBean

I am not sure if it isn't finding the binding file on the class path sometimes? Perhaps this could happen if you clean and restart and it fails to find binding file until you start again?

I am just guessing. It is so hard to track these issues down without having working code/scenarios.

ctoestreich commented 11 years ago

This is the block of code from cxf where it is failing. It is the return cls.cast(proxy); that is throwing the null. I am not sure if maybe the cxf client proxy is getting thrown away or coming through null. You should be able to get the cxf source (really easy if using intellij) and debug that line and see what is happening in your code and what exactly is null.

C

public static T getProxy(Class cls, Object obj) { InvocationHandler ih = new ExtensionInvocationHandler(obj); / * If we put proxies into the loader of the proxied class, they'll just pile up. / Object proxy = null; try { proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {cls}, ih); } catch (Throwable ex) { // Using cls classloader as a fallback to make it work within OSGi
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); if (contextLoader != cls.getClassLoader()) { proxy = Proxy.newProxyInstance(cls.getClassLoader(), new Class[] {cls}, ih); } else { if (ex instanceof RuntimeException) { throw (RuntimeException)ex; } throw new RuntimeException(ex); } } return cls.cast(proxy); }

tomwidmer commented 3 years ago

I have this issue (still stuck on a very old version of Grails - 2.2.1). From debugging the code, the problem looks bizarre:

For me, when the exception occurs, cls is SoapFault, but if I do proxy.getClass().getInterfaces(), it shows the only implemented interface or the proxy is SoapBody (not the expected SoapFault). This doesn't match the newProxyInstance line at all! Re-evalutating the newProxyInstance expression in the debugger continues to return the same, incorrect proxy. I don't know whether this is a class loader bug (probably in Grails) or a VM bug.

Oddly, it does seem to work sometimes, if you clean and rebuild a few times. I don't know if there's a weird race condition of some kind relating to the order of class loading, or allocated class names, etc.