J2EE application clients
The service client programming model for J2EE clients is about accessing a remote web service from a J2EE client.
The web service client is deployed as a standard jar archive plus additional <service-ref> elements in the
application-client.xml deployment descriptor.
Once the J2EE application client jar is deployed on a JBoss instance, it can be accessed by a separate standalone Java program. On JBoss 4.0.3SP1 and earlier, this program must be running on the same system that holds the J2EE application jar. This means that you must run a small jboss instance on the client system to use the J2EE application client web service model. JBoss 4.0.4 will allow the standalone Java client to access web services defined in a J2EE application client jar on a remote system.
Service Endpoint Interface
The SEI declares the methods through which to access the remote web service.
We use the same service endpoint interface as for the EJB service endpoint.
Web Service Description Language
Any web service client must have access to the wsdl that describes the remote webservice. The wsdl can be part of the client
deployment or may be obtained at runtime before the client accesses the remote web service.
We use the same wsdl as for the EJB service endpoint or the Java service endpoint.
At deploy time the important difference to the server side wsdl is that the client side wsdl must already contain
the correct service endpoint location, otherwise it would not know where to send the SOAP request to. It is also possible
that the client side wsdl contains no <service> element at all, in that case the service location must be provided
dynamically be the client code.
JAX-RPC Mapping Files
The web service client must have access to the same mapping information as described for the EJB service endpointor the Java service endpoint. The jaxrpc mapping file must be part of the client deployment, it cannot be obtained at runtime.
Packaging the web service client
The standard deployment descriptor for J2EE clients application-client.xml, declares the service reference.
<application-client xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd" version="1.4"> <display-name>webservice client app</display-name> <service-ref> <service-ref-name>service/OrganizationServiceEJB</service-ref-name> <service-interface>javax.xml.rpc.Service</service-interface> <wsdl-file>META-INF/wsdl/server-ejb.wsdl</wsdl-file> <jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> </service-ref> <service-ref> <service-ref-name>service/OrganizationServiceJSE</service-ref-name> <service-interface>com.underworld.crimeportal.OrganizationEndpointService</service-interface> <wsdl-file>META-INF/wsdl/server-web.wsdl</wsdl-file> <jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> </service-ref> </application-client>
The <service-ref-name> is the JNDI name in the client's environment context under which the jaxrpc service is bound.
For the the exact lookup syntax see below. The example above uses two different ways to bind a jaxrpc service. The first
uses the generic javax.xml.rpc.Service interface, the second uses an application specific service interface that
extends javax.xml.rpc.Service
Service Interface
It is possible to provide a typed service interface to web service clients that extends the standard
javax.xml.rpc.Service interface. In this way the client looks up a service from JNDI that already
has application specific semantics.
public interface OrganizationEndpointService extends javax.xml.rpc.Service { public OrganizationEndpoint getOrganizationPort() throws javax.xml.rpc.ServiceException; }
Deploy the Web Service client to JBoss
This follows the normal deployment procedure for application clients in JBoss. There are no web service specific info
messages.
Accessing the Service from Java
Here is a simple test case, that shows how a java client does a lookup of the service interface, then obtains the
desired port, and finally invokes getContactInfo on the service endpoint interface.
public class ClientSideApplTestCase extends TestCase { /** Test access to the EJB webservice via an app client */ public void testApplClientAccessEJB() throws Exception { InitialContext iniCtx = getInitialContext(); javax.xml.rpc.Service service = (javax.xml.rpc.Service)iniCtx.lookup("java:comp/env/service/OrganizationServiceEJB"); OrganizationEndpoint endpoint = (OrganizationEndpoint)service.getPort(OrganizationEndpoint.class); String info = endpoint.getContactInfo("mafia"); assertEquals("The 'mafia' boss is currently out of office, please call again.", info); } /** Test access to the JSE webservice via an app client */ public void testApplClientAccessJSE() throws Exception { InitialContext iniCtx = getInitialContext(); OrganizationEndpointService service = (OrganizationEndpointService)iniCtx.lookup("java:comp/env/service/OrganizationServiceJSE"); OrganizationEndpoint endpoint = service.getOrganizationPort(); String info = endpoint.getContactInfo("mafia"); assertEquals("The 'mafia' boss is currently out of office, please call again.", info); } /** Build the InitialContext */ private InitialContext getInitialContext() throws NamingException { Properties env = new Properties(); env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming.client:org.jboss.naming"); env.setProperty(Context.PROVIDER_URL, "jnp://localhost:1099"); env.setProperty("j2ee.clientName", "ws4ee-client"); return new InitialContext(env); } }
This example also shows the use of the j2ee.clientName JNDI property. For more detailed information see
Comments