views:

131

answers:

0

BACKGROUND: Current Grails application has to interact w/ a 'legacy' web service from a third party vendor - (systinet) Used the Apache CXF Wsdl2Java tool to generate complex types and service interfaces. Pretty standard stuff so far and this works perfectly from Java.

After writing some test classes and main() methods to exercise the Java code, and providing a thin layer above for a simplified interface, I wanted to call this code from Grails app. Specifically, Grails controllers, services, quartz jobs ,and the like. However, this is where things got interesting.

First stack trace from Grails CXF plug-in it was causing a FileNotFoundException. Beyond not needing to load a WSDL definition - since I already successfully ran CXF's Wsdl2Java tool, it seems there is something I'm missing here. Tried substituting a file:/// url***for the WSDL and got another exception.

At the end of all this -- removing plug-ins of any sort, I reconfigured the project with the CXF dependencies by hand** and now got a MarshallingException, essentially from the CXF-generated code! Which by the way executes perfectly from a Java class.

Someone I am sure must've come across this issue in your Grails integrations. As always your guidance is most appreciated!

1)Why in the Grails application, does the runtime attempt to parse the wsdl ? Also, note JDK versions are same java version "1.6.0_12".

2) Any CLASSPATH workarounds anyone can suggest? I guess an alternative approach is to re-write the Java middle layer calls with GroovyWS but that would be quite an effort - given number of services and the custom types the vendor has baked in.

static {
    URL url = null;
    try {
        url = new URL("http://mydevhost:9080/wasp/bmc-security/ctsa/person");
    } catch (MalformedURLException e) {
        System.err.println("Can not initialize the default wsdl from server");
        // e.printStackTrace();
    }
    WSDL_LOCATION = url;
}

/* static { URL url = null; try { url = new URL( "file:///C:/Projects/beta/workspace/reqmgr3/wsdl/Person.wsdl" ); url.getPath(); } catch (MalformedURLException e) { System.err.println("Can not initialize the default wsdl from file system"); // e.printStackTrace(); } WSDL_LOCATION = url; } */

`

**Stack traces

INFO: No Trust Decider configured for Conduit ... Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit finalizeConfig INFO: No Basic Auth Supplier configured for Conduit '... Aug 11, 2010 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit prepare INFO: Chunking is set at 2048. Aug 11, 2010 6:26:16 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO: Interceptor has thrown exception, unwinding now org.apache.cxf.interceptor.Fault: Marshalling Error: com.systinet.wsdl.com.bmc.security.ess.webservice.holder.ArrayOfLog inPairHolder is not known to this context at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:132) at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:42) at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:30) at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:73) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:148) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:215) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122) at $Proxy44.login(Unknown Source) ... ... 2 more

UPDATE 15-Aug:

Decided, out of both modularity and expediency, to put this code into separate WAR project, which will offer its ltd. services, rather than expose the original vendor web services, which are too unwieldy.

This project will be pure Java and leverages the Metro 2.0.1 runtime, which is around 16mb.

Calling the Java-based middleware services from Grails now becomes possible, after clearing out the lib and src/java folders -- basically just installed ws-client plugin and setup local services such as the following:

import groovyx.net.ws.WSClient 
import org.grails.plugins.wsclient.service.WebService 

class LocalPersonService { 
    WebService webService 
    groovyx.net.ws.WSClient  _proxy 
    static final String PERSON_WSDL_URL = "http://localhost:9090/pri/PersonServicePort?wsdl" 

    def transactional = false 

    def getPersonDetails( String customerId, User userAccount, String userCredential ) { 
        // must cache the proxy 
        if ( _proxy == null ) { 
            print( "init proxy.  Parsing wsdl..." ) 
            try { 
                _proxy = webService.getClient(PERSON_WSDL_URL) 
            } 
            catch ( Throwable tr ) { println( tr.getMessage() ) } 
        } 

        // method shall return a  (com.siventures.example.service.PersonDetails) 
        return _proxy.getPersonDetails( customerId, userAccount, userCredential, ... ) 
    }