[Mulgara-svn] r1909 - in trunk/src/jar/util: . java/org/mulgara/util

alexhall at mulgara.org alexhall at mulgara.org
Fri Feb 5 20:46:09 UTC 2010


Author: alexhall
Date: 2010-02-05 12:46:08 -0800 (Fri, 05 Feb 2010)
New Revision: 1909

Modified:
   trunk/src/jar/util/build.xml
   trunk/src/jar/util/java/org/mulgara/util/Rmi.java
Log:
Adding a new method to export an RMI object using the Interruptible RMI socket factory. Also adding a central point for configuring default behavior of interruptible RMI operations in the application.

Modified: trunk/src/jar/util/build.xml
===================================================================
--- trunk/src/jar/util/build.xml	2010-02-05 20:43:07 UTC (rev 1908)
+++ trunk/src/jar/util/build.xml	2010-02-05 20:46:08 UTC (rev 1909)
@@ -20,6 +20,8 @@
   <path id="util-classpath">
 
     <path refid="common-classpath"/>
+
+    <fileset file="${bin.dir}/${config.jar}"/>
   </path>
 
   <path id="util-test-classpath">
@@ -51,7 +53,7 @@
   </target>
 
   <target name="util-compile"
-          depends="-util-prepare"
+          depends="-util-prepare, config-jar"
           description="Compiles all util related files included generated
                        source code"
           unless="util.classes.uptodate">

Modified: trunk/src/jar/util/java/org/mulgara/util/Rmi.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/Rmi.java	2010-02-05 20:43:07 UTC (rev 1908)
+++ trunk/src/jar/util/java/org/mulgara/util/Rmi.java	2010-02-05 20:46:08 UTC (rev 1909)
@@ -22,6 +22,8 @@
 import java.rmi.server.UnicastRemoteObject;
 
 import org.apache.log4j.Logger;
+import org.mulgara.config.MulgaraConfig;
+import org.neilja.net.interruptiblermi.InterruptibleRMISocketFactory;
 
 /**
  * A utility to centralize the port handling for RMI objects.
@@ -41,12 +43,22 @@
   /** Generation UID */
   private static final long serialVersionUID = -8087526398171872888L;
 
+  /** Java system property used to set the default RMI client object port. */
   public static final String CLIENT_OBJECT_PORT = "mulgara.rmi.objectPort";
-
+  
+  /** Java system property used to enable/disable the use of interruptible RMI sessions. */
+  public static final String INTERRUPT = "mulgara.rmi.interrupt";
+  
   /** The default port used for exporting objects. */
   protected static int defaultPort = 0;
-
-  // Check if a system property has been set for the default port
+  
+  /**
+   * Flag used to configure the enabling of interruptible RMI sessions by default.
+   * Initially set from the value of the {@link #INTERRUPT} system property, if present.
+   */
+  protected static Boolean defaultInterrupt = null;
+  
+  // Check if a system property has been set for the default port or interruptible RMI.
   static {
     String val = System.getProperty(CLIENT_OBJECT_PORT);
     if (val != null) {
@@ -56,6 +68,10 @@
         logger.warn("Unable to parse the client peer port for RMI: " + val);
       }
     }
+    val = System.getProperty(INTERRUPT);
+    if (val != null) {
+      defaultInterrupt = Boolean.valueOf(val);
+    }
   }
 
 
@@ -98,6 +114,24 @@
    * @throws RemoteException There was an error exporting the object.
    */
   public static Remote export(Remote obj) throws RemoteException {
+    return export(obj, false);
+  }
+  
+  
+  /**
+   * Exports an object through RMI, enabling interruptible operations on the exported
+   * object if specified. If a known port is configured then it will be used to export the
+   * object, otherwise a random anonymous port will be chosen.
+   * @param obj The object to export.
+   * @param interruptible <tt>true</tt> to enable interruptible RMI operations on the exported object.
+   * @return An exported object.
+   * @throws RemoteException There was an error exporting the object.
+   */
+  public static Remote export(Remote obj, boolean interruptible) throws RemoteException {
+    if (interruptible) {
+      InterruptibleRMISocketFactory sf = new InterruptibleRMISocketFactory();
+      return UnicastRemoteObject.exportObject(obj, defaultPort, sf, sf);
+    }
     if (defaultPort == 0) return UnicastRemoteObject.exportObject(obj);
     return UnicastRemoteObject.exportObject(obj, defaultPort);
   }
@@ -114,6 +148,20 @@
     return UnicastRemoteObject.unexportObject(obj, false);
   }
 
+  
+  /**
+   * Sets the default system behavior for enabling/disabling interruptible RMI operations,
+   * based on the <tt>RMIInterrupt</tt> property from the specified Mulgara XML config file.
+   * If the default behavior has already been set by the {@link #INTERRUPT} system property,
+   * then this method has no effect.
+   * @param config A Mulgara XML configuration.
+   */
+  public static void configure(MulgaraConfig config) {
+    if (defaultInterrupt == null && config.hasRMIInterrupt()) {
+      defaultInterrupt = Boolean.valueOf(config.getRMIInterrupt());
+    }
+  }
+  
 
   /**
    * Sets the port for the default exporter to use. 
@@ -132,6 +180,48 @@
     return defaultPort;
   }
 
+  
+  /**
+   * Manually override the configured system behavior for interruptible RMI operations.
+   * @param interrupt <tt>true</tt> to enable interruptible RMI sessions where appropriate.
+   */
+  public static void setDefaultInterrupt(boolean interrupt) {
+    defaultInterrupt = Boolean.valueOf(interrupt);
+  }
+  
+  
+  /**
+   * Get the configured system default enabled status of interruptible RMI operations.
+   * The order of precedence is as follows:
+   * <ol>
+   *   <li>If the default has been set in code via the {@link #setDefaultInterrupt(boolean)}
+   *       method, return that value.</li>
+   *   <li>The value of the {@link #INTERRUPT} Java system property, if present.</li>
+   *   <li>The value set by the Mulgara XML config file via the {@link #configure(MulgaraConfig)}
+   *       method, if applicable.</li>
+   *   <li>If the default has not been configured by any of the above means, return <tt>false</tt>.</li>
+   * </ol>
+   * @return <tt>true</tt> if interruptible RMI operations should be enabled by default.
+   */
+  public static boolean getDefaultInterrupt() {
+    if (defaultInterrupt != null) return defaultInterrupt.booleanValue();
+    return false;
+  }
+  
+  
+  /**
+   * Determines whether the current thread is an RMI server thread that has been
+   * interrupted by the client. This method only gives useful results if the remote
+   * object in question was exported using the {@link #export(Remote, boolean)} method
+   * with the <tt>interruptible</tt> parameter set to <tt>true</tt>.
+   * @return <tt>true</tt> if the current thread is an RMI server thread, and the underlying
+   *         socket has been closed by the client.
+   */
+  public static boolean isInterrupted() {
+    return InterruptibleRMISocketFactory.isCurrentThreadRMIServer() &&
+        !InterruptibleRMISocketFactory.isCurrentRMIServerThreadSocketAlive();
+  }
+  
 
   /**
    * Unexport this object from RMI.




More information about the Mulgara-svn mailing list