3 Replies Latest reply on Oct 17, 2005 8:03 PM by Jason Greene

    ws4ee client  and standalone application client (thick clien

    Anatoly Osiko Newbie

      I am asking the experts and the community to share the "best practice" views on the following architecture: standalone application (JVM) uses web services (soap) for communication with the JBoss server side application, using J2EE or JSE web services endpoints.

      I have had my bit of experience and read through a few books on the topic, wiki documents, etc. So my experience so far....

      In fact, I had no problems with the deployment of web services (server side) on the JBoss (all the latest versions till 4.0.3) .
      As for the client ... still struggling with finding an acceptable solution.

      In our case it is a standalone JVM application(s) running on the user PC (i.e.not on the jboss server host). The appealing path to follow was to use j2ee client application paradigm with JNDI lookup for the WS proxy.
      For the sake of consistency and and to save time, for the client side I preferred to use jboss's collection of the client jars, rather than using sun's wsdk.

      Leaving the details aside (document/literal, wrapped style, top dow design from wsdl description, jndi.properties, all the deployment artifacts, etc), I report, that everything worked fine when the standalone client was tested on the same host, that ran Jboss server.
      When I attempted to run the same client (with all the jboss client jars) from another host, I consistently received the following error message, despite the mapping file (DataMgr-mapping.xml) being present in the client's jar:

      [java] Context client name: datamgr-client [java] javax.naming.NamingException: Could not dereference object [Root exception is java.lang.IllegalStateException: Cannot find resource: META-INF/DataMgr-mapping.xml] [java] at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1135) [java] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:690) [java] at org.jboss.naming.client.java.javaURLContextFactory$EncContextProxy.invoke(javaURLContextFactory.java:120) [java] at $Proxy0.lookup(Unknown Source) [java] at javax.naming.InitialContext.lookup(InitialContext.java:347) [java] at org.imvs.qc.service.BaseProxy.getServiceProxy(BaseProxy.java:146) [java] at org.imvs.qc.service.BaseProxy.init(BaseProxy.java:96) [java] at org.imvs.qc.service.BaseProxy.(BaseProxy.java:80) [java] at org.imvs.qc.service.datamgr.client.DataMgrProxy.(DataMgrProxy.java:65) [java] at org.imvs.qc.client.WebServiceTest.main(WebServiceTest.java:47)
      [java] Caused by: java.lang.IllegalStateException: Cannot find resource: META-INF/DataMgr-mapping.xml
      [java] at org.jboss.webservice.metadata.serviceref.ServiceRefMetaData.getJavaWsdlMappingURL(ServiceRefMetaData.java:111)
      [java] at org.jboss.webservice.metadata.serviceref.ServiceRefMetaData.getJavaWsdlMapping(ServiceRefMetaData.java:118)
      [java] at org.jboss.webservice.client.ServiceObjectFactory.getObjectInstance(ServiceObjectFactory.java:133)
      [java] at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:301)
      [java] at org.jnp.interfaces.NamingContext.getObjectInstance(NamingContext.java:1110)
      [java] at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1127)
      [java] ... 9 more
      [java] Could not initialise BaseProxy object: Could not dereference object
      [java] java.lang.NullPointerException
      [java] at org.imvs.qc.service.datamgr.client.DataMgrProxy.getInstruments(DataMgrProxy.java:75)
      [java] at org.imvs.qc.client.WebServiceTest.main(WebServiceTest.java:49)

      That was the end of what seemed to be the final stretch before finalizing with the web services adapter(services locator, etc) between the client and the server side.

      The idea of utilizing JNDI lookup for the remote client seems very appealing and elegant,especially, if JBoss can be configured, if I get it right, to serve jndi request via http protocol.
      Otherwise, j2ee style of webservice appears to be applicable only for the case when one j2ee container deployed application communicates with another j2ee container deployed application.

      Our application with rich GUI and supposed to be installed on the user's desktop is a classical example of a "thick" client, however not to the extent, that we need to run an instance of JBoss server on each user's PC.

      Believing that dynamic proxy is the cleanest solution, I am now trying to make use of JBoss's ServiceFactoryImpl. Errors, erros - trying to resolve step by step ....

      Yet, can anyone tell me, if I need to abandon ws4ee/jndi web services client solution in my case?

        • 1. Re: ws4ee client  and standalone application client (thick c
          mka Newbie

          Hi there, were you ever able to resolve this? I'm experiencing the exactly the same problem.

          • 2. Re: ws4ee client  and standalone application client (thick c
            Anatoly Osiko Newbie

            Someone (mka <do-not-reply@jboss.com> is asking whether I was able to resolve the problem...

            Well, I have to abandon this ws4ee (jndi lookup) approach, until I receive some re-assurance from the people who knows ws4ee technology better. There are some materials around, indicating that jndi lookup can be applied to the standalone clients as well (on the remote machine?). OK, may be, jndi has nothing to do with it - what can I see, there error message is created on the client side.

            Now I make use of JBoss's ServiceFactoryImpl to create the service proxy dynamically.
            This is my test class.
            Please, note the mapping file location: META-INF/DataMgr-mapping.xml
            and the following way to obtain the required URL object from that resource location:
            mappingUrl = classloader.getResource(mappingLocation);

            
            package org.imvs.qc.client;
            
            import java.net.URL;
            import java.io.File;
            
            import javax.xml.rpc.Call;
            import javax.xml.rpc.Service;
            import javax.xml.rpc.ServiceFactory;
            import javax.xml.rpc.JAXRPCException;
            import javax.xml.rpc.ParameterMode;
            import javax.xml.rpc.JAXRPCException;
            import javax.xml.namespace.QName;
            import java.rmi.RemoteException;
            
            public class WSTestSansJNDI
            {
             public URL wsdlUrl;
             public String ns;
             public URL mappingUrl;
             private ClassLoader classloader;
            
             /**
             * Dynamic Proxy web service client without JNDI lookup.
             *
             * @param wsdlLocation - url of the WSDL file, e.g "http://myhost:8080/qc/datamgr/doIt?wsdl"
             * @param ns - this service's namespace,e.g. "http://org.imvs.qc.service.datamgr"
             * @param mappingLocation - actually, a resource type location of jaxrpc mapping file,
             * e.g "META-INF/DataMgr-mapping.xml"
             */
            
            public WSTestSansJNDI(String wsdlLocation, String ns, String mappingLocation)
             {
             setClassLoader();
            
             this.ns = ns;
            
             try
             {
             if (wsdlLocation != null)
             {
             wsdlUrl = new URL(wsdlLocation);
             }
            
             if (mappingLocation != null)
             {
             mappingUrl = classloader.getResource(mappingLocation);
            
             }
             }
             catch (Exception ex)
             {
             System.out.println(ex.getMessage());
             }
             } /**
             * Set the class loader
             */
             public void setClassLoader()
             {
             classloader = getClass().getClassLoader();
             }
            
             /**
             * Gets the class loader
             *
             * @return ClassLoader - the class loader
             */
             public ClassLoader getClassLoader()
             {
             return classloader;
             } public void test() throws Exception
             {
             try
             {
             QName serviceName = new QName(ns, "DataMgrService");
             QName portName = new QName(ns,"DataMgrPort");
            
             org.jboss.webservice.client.ServiceFactoryImpl factory =
             (org.jboss.webservice.client.ServiceFactoryImpl) ServiceFactory.newInstance();
             Service service = factory.createService(wsdlUrl, mappingUrl, null, serviceName, null);
             org.imvs.qc.service.datamgr.DataMgr port =
             (org.imvs.qc.service.datamgr.DataMgr) service.getPort(
             portName, org.imvs.qc.service.datamgr.DataMgr.class);
            
             org.imvs.qc.service.datamgr.GetInstrumentsResponse response = port.getInstruments(
             new org.imvs.qc.service.datamgr.GetInstrumentsRequest());
            
             org.imvs.qc.instrument.Instrument[] instruments =
             (org.imvs.qc.instrument.Instrument[]) response.getInstruments();
            
             for (int i = 0; i < instruments.length; i++)
             {
             org.imvs.qc.instrument.Instrument instr = (org.imvs.qc.instrument.Instrument) instruments;
             System.out.println(instr.toString());
             }
             }
             catch (RemoteException rex)
             {
             System.out.println("RemoteException");
             rex.printStackTrace(System.out);
             }
             catch (Exception ex)
             {
             ex.printStackTrace(System.out);
             }
            
             }
            
             public static void main(String[] args)
             throws Exception
             {
             System.out.println("WSTestSansJNDI.");
             System.out.println("arguments: wsdlUrl = " + args[0] + " ns=" + args[1]
             + " mapping=" + args[2]);
             WSTestSansJNDI test = new WSTestSansJNDI(args[0],args[1],args[2]);
             test.test();
             }
             }
            
            


            • 3. Re: ws4ee client  and standalone application client (thick c
              Jason Greene Master

              Currently the J2EE application client jar has to be deployed on the same system as the standalone client app. This means in the current release, you need to have a minijboss running on the client system. We are going to add support for remote client access in 4.0.4.

              http://jira.jboss.org/jira/browse/JBWS-438

              -Jason