Globus > Toolkit > Documents > Development > 3.9.2 <

GT 4.0 Developer Notes: Java WS Core

Tomcat

To deploy GT4 installation into Tomcat run:

cd $GLOBUS_LOCATION
ant -f share/globus_wsrf_common/tomcat/tomcat.xml deployTomcat -Dtomcat.dir=<tomcat.dir>
Where <tomcat.dir> is an absolute path to the Tomcat installation directory.

To create a .war of GT4 installation do:

cd $GLOBUS_LOCATION
ant -f share/globus_wsrf_common/tomcat/tomcat.xml war -Dwar.file=<war.file>
Where <war.file> specifies an absolute path of the war file.

Please note that deploying a war file might not be enough to have a working GT4 deployment. For example, in some cases the xalan.jar must be placed in the endorsed directory of the container.

Testing

Conventions

Group your tests under PackageTests.java and/or SecurityTests.java (The naming is important because these names are used to discover the tests dynamically). Put all tests that require any type of credentials in SecurityTests.java test suite.

Running

To execute the tests on GT4 install run (assuming the tests have been deployed into GT4 install):

cd $GLOBUS_LOCATION
ant -f share/globus_wsrf_test/runtests.xml runServer -Dtests.jar=<test.jar>
Where <test.jar> is an absolute path to the jar file that contains the tests. By default, the tests that use a container will try to access a container running at http://localhost:8080/wsrf/services/. To specify a different container use -Dtest.server.url=<url> property. To execute PackageTests only specify -DbasicTestsOnly=true. To execute SecurityTests only specify -DsecurityTestsOnly=true.
The test reports will be put in $GLOBUS_LOCATION/share/globus_wsrf_test/test-reports directory by default. The different test reports directory can be specified by passing -Djunit.reports.dir=<directory>.

Activation

Service

Axis RPCProvider

Instance of a service is always created on an invocation. It depends on the 'scope' setting if one instance of the service is used for all invocations (Application scope), if one instance is created per invocation (Request scope), or one instance per session (Session scope). The Request scope is default (if scope parameter is not set in the deployment descriptor). If service implements the javax.xml.rpc.server.ServiceLifecycle interface the lifecycle methods they will be called accordingly to the scope setting as a service instance is created and destroyed. For example, in Application scope destroy() will be called on container shutdown, and in Request scope it will be called after the service method is called. JAAS credentials will not be associated with a thread when a service instance is created.

Globus RPCProvider

Only Application and Request scopes are supported.
If Request scope things behave just like in Axis RPCProvider (service/providers instances are created per invocation, no JAAS credentials, ServiceLifecycle methods called right before and after service method invocation).
If Application scope service/provider instances are created either on first invocation or on container startup if "loadOnStartup" parameter in the deployment descriptor is set:

<parameter name="loadOnStartup" value="true'/>
This will work in the same way in the standalone container and in Tomcat. If the service or the container is configured with a security descriptor, the appropriate credentials will be associated with the thread during activation (using JAAS). Also, during activation a basic Axis MessageContext will be associated with the thread with only Constants.MC_HOME_DIR, Constants.MC_CONFIGPATH, and the right target service properties set (see MessageContext Properties section for details). If service or providers implement the javax.xml.rpc.server.ServiceLifecycle interface the lifecycle methods will be called accordingly.

ResourceHome

ResourceHome will be activated on the first service invocation or during container startup if "loadOnStartup" parameter is set. If ResourceHome get activated in such ways, proper MessageContext and/or JAAS subject will be associated with the thread. Also proper MessageContext and/or JAAS subject will be associated with the thread if the ResourceHome gets activated by a separate thread directly looking up the ResourceHome implementation in JNDI. This actually applies to all resource entries directly defined under service entries in jndi-config.xml and configured with org.globus.wsrf.jndi.BeanFactory factory.

ServiceResourceHome

If you are using ServiceResourceHome please make sure to deploy the service with "loadOnStartup" option enabled and in Application scope. That will ensure that the ResourceHome is initialized with the right service/resource.

MessageContext Properties

In the standalone container the Constants.MC_HOME_DIR and Constants.MC_CONFIGPATH properties will usually point to the same directory. However, in Tomcat they will point to two different directories so make sure to use the right property to load the configuration files.

Local Invocations

Services in the container can be invoked locally. Local invocations work just like remote invocations (all handlers are called, messages get serialized/deserialized) but messages do not travel over the network - everything happens in memory.

Local invocations can only be made on the server side and only when a Axis MessageContext is associated with a current thread. URLs with "local" protocol name are used for local invocations. To invoke a service locally do:
1

Register "local" protocol handler:

import org.globus.axis.transport.local.LocalTransportUtils;
...
LocalTransportUtils.init();
...
2

Create a service URL with "local" protocol:

URL url = new URL("local:///wsrf/services/MyService");
3

Configure the service stub for local invocation and make the call:

MyServiceAddressingLocator locator = 
       new MyServiceAddressingLocator();
MyService port = locator.getMyServicePort(url);

LocalTransportUtils.enableLocalTransport((Stub)port);

port.hello();

Tomcat

Special configuration is required to enable local invocations in Tomcat. The "local" protocol URL handler must be installed in a different way. [ADD MORE INFO HERE HOW].

Using ResourceHomeImpl

If ResourceHomeImpl is configured with resource class that implements the PersistentResource interface it will store the resource objects wrapped in Java SoftReference. That allows the JVM to automatically reclaim these resource objects thus reducing the memory usage. Since the JVM can decide to reclaim these objects at any point sometimes a resource object can be reclaimed between two subsequent invocations on the same resource. This for example can cause the state of the resource to be reloaded from disk on each call.
To prevent the JVM from reclaiming the resource objects so quickly a cache can be setup up to hold direct references to these objects. We provide a basic LRU (least recently used) cache implementation. Other cache implementations can be used as long as they implement the org.globus.wsrf.utils.cache.Cache interface.

To configure a cache for ResourceHomeImpl first define a cache resource:

<resource name="cache" 
             type="org.globus.wsrf.utils.cache.LRUCache">
  <resourceParams>
     <parameter>
        <name>factory</name>
        <value>org.globus.wsrf.jndi.BeanFactory</value>
     </parameter>
     <parameter>
        <name>timeout</name>
        <value>120000</value>
     </parameter>
  </resourceParams>
</resource>

In this case a LRU cache is configured. The "timeout" parameter (in ms) is used to specify the idle time of the resource object before it is removed from cache.
The same cache resource can be reused in different services but usually once cache per service will be configured.

Once the cache resource is defined add the "cacheLocation" parameter to the service home resource. The "cacheLocation" parameter value is the JNDI name of the cache resource:

<service name="CounterService">
   <resource name="home" type="...">
      <resourceParams>
         ...
         <parameter>
            <name>cacheLocation</name>
            <value>java:comp/env/CounterService/cache</value>
         </parameter>
         ...
      </resourceParams>
   ...

Please note that once the object is removed from the cache it is still up to the JVM to actually reclaim the object.

Proxy Support

A basic proxy support is provided. A org.globus.wsrf.proxy.port system property can be set to the port of the proxy server (the proxy server must run on the same machine as the container). This will make any code that uses ServiceHost or AddressingUtils API return the address of the proxy server instead of the container. This could be useful for example for debugging purposes.
The org.globus.wsrf.proxy.port system property can be passed to globus-start-container script via GLOBUS_OPTIONS environment property. For example:

setenv GLOBUS_OPTIONS="-Dorg.globus.wsrf.proxy.port=5555"
globus-start-container
Please note that not all of the core code will obey the proxy port setting.