The preferred way of getting a reference to a stub is by using the generated
service class as we've seen in the two hello world examples. A client application
will simply look the service object up from JNDI and create a stub using the
generated getXXPort
method. In addition to the default way of
getting a stub, the Novell exteNd WSSDK supports a number of other methods for finding
service. This chapter is divided into the following sections:
The Novell exteNd WSSDK supports a service factory, which can be used to create services. This service factory should not be confused with the factory used in previous versions. The new service factory is part of the standard JAXRPC API's. Below is an example of using the service factory:
package naming; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceFactory; import helloWSDL.Hello; import helloWSDL.HelloService; public class ServiceFactoryClient { public static void main(String[] args) throws Exception { | // must set the javax.xml.rpc.ServiceFactory property to | // com.sssw.jbroker.web.xml.rpc.ServiceFactoryDelegate, e.g.: | System.setProperty(ServiceFactory.SERVICEFACTORY_PROPERTY, | "com.sssw.jbroker.web.xml.rpc.ServiceFactoryDelegate"); | | // create a Novell exteNd WSSDK service factory | ServiceFactory factory = ServiceFactory.newInstance(); | | // lookup the service for Hello | QName qname = new QName("http://www.helloWSDL", "HelloService"); | HelloService svc = (HelloService) factory.createService(qname); | | // get the hello stub | Hello hello = (Hello) svc.getHelloPort(); | | // invoke the service | System.out.println(hello.sayHello()); } }
The service classes generated by the Novell exteNd WSSDK are Serializable and Referenceable. This makes it possible to bind the services in JNDI using arbitrary JNDI providers that support this mechanism. Here is a client that stores a service into JNDI:
package naming; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import com.sssw.jbroker.web.Binding; import com.sssw.jbroker.web.ServiceFactory; public class Client { private static String _userDir = "file://" + System.getProperty("user.dir"); public static void main(String[] args) throws Exception { | // create the initial context | Hashtable env = new Hashtable(11); | env.put(Context.INITIAL_CONTEXT_FACTORY, | "com.sun.jndi.fscontext.RefFSContextFactory"); | env.put(Context.PROVIDER_URL, _userDir); | InitialContext ctx = new InitialContext(env); | | // create reference to service using constructor | helloWSDL.HelloService service = new helloWSDL.HelloServiceImpl(); | | // bind objects | if (args[0].equals("-bind")) { | | System.out.println("binding objects ..."); | | ctx.rebind("hello", service); | } | | // unbind objects | if (args[0].equals("-unbind")) { | | System.out.println("unbinding objects ..."); | | ctx.unbind("hello"); | } | | // lookup objects | if (args[0].equals("-lookup")) { | | System.out.println("looking up objects ..."); | | helloWSDL.HelloService hello = (helloWSDL.HelloService) ctx.lookup("hello"); | | System.out.println(service); | } } }
The above test program requires that you have the
File System Service Provider
in your CLASSPATH
. Please modify the above program (if necessary) to
work with your favorite JNDI provider.
The Novell exteNd WSSDK also supports URL based JNDI lookups. The lookup string format used by Novell exteNd WSSDK is shown below:
xmlrpc:<protocol>:<service>[@<location>[#<URI>]]
Examples include:
xmlrpc:soap:hello.HelloService xmlrpc:soap:hello.HelloService@http://localhost:8080/services/hello xmlrpc:soap:hello.HelloService@http://localhost:8080/services/hello#urn:HelloApp
When going from WSDL to Java, the location string and URI are typically not needed since these are extracted from the WSDL document and embedded into the generated stub. The example below looks up and invokes the AltaVista Babel service:
package babel; import javax.naming.InitialContext; public class Client { public static void main(String[] args) throws Exception { | String text = args.length > 0 ? args[0] : "Hello World"; | InitialContext ctx = new InitialContext(); | BabelFishService service = | (BabelFishService) ctx.lookup("xmlrpc:soap:babel.BabelFishService"); | BabelFishPortType babel = service.getBabelFishPort(); | System.out.println(text + " => " + babel.babelFish("en_fr", text)); } }
Note that the URL based lookup does not require you to specify an initial context factory. Although looking up stubs from JNDI has been deprecated, the Novell exteNd WSSDK still supports lookup of stubs for existing applications. However, as mentioned above the preferred way is to use JNDI with services only.
Under JDK 1.3 and higher, the Novell exteNd WSSDK runtime can use a dynamic proxy class
to implement the stub. This means that the stub class does not have to be generated
and included in the CLASSPATH
. When using rmi2soap the proxy
stub will not have access to binding information or the service port type. These
and other properties must be set on the proxy prior to invoking.
Note: The dynamic stub also doesn't contain other information from the SOAP binding such as SOAPAction, which may lead to interoperability problems when invoking Web services implemented using other vendor's toolkits. Below is an example of setting the schema URI on the stub.
stub._setProperty("xmlrpc.schema.uri", "http://www.w3.org/1999/XMLSchema");
In previous versions of this product, the factory was the preferred way of creating references to a remote interface. While this API may still be used for backwards compatibility, it has been deprecated in favor of the new standard API's. The example below shows how to use the service factory to create stub objects:
package naming; import com.sssw.jbroker.web.Binding; import com.sssw.jbroker.web.ServiceFactory; public class OldServiceFactory { public static void main(String[] args) throws Exception { | Binding binding = args.length > 0 ? | new Binding("soap", args[0]) : | new Binding("soap", "http://localhost:9090/hello"); | hello.Hello hello = (hello.Hello) | ServiceFactory.create(hello.Hello.class, binding); | System.out.println(hello.sayHello()); } }
When the stub is created by running the wsdl2java compiler, it is normally possible to create the stub using the simple create method on the ServiceFactory class since WSDL documents often contain binding information.
The ServiceFactory
has another create method that takes an additional
parameter that specifies the service port type. This method must be used when
using dynamic proxies.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.