You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by hl...@apache.org on 2005/01/04 02:06:22 UTC

cvs commit: jakarta-hivemind/src/documentation/content HiveMind-QuickReference.doc

hlship      2005/01/03 17:06:22

  Modified:    src/documentation/content/xdocs index.xml site.xml
               framework/src/java/org/apache/hivemind/impl
                        ProxyBuilder.java RegistryInfrastructureImpl.java
               .        forrest.properties status.xml
               framework/src/java/org/apache/hivemind/test
                        HiveMindTestCase.java
               library/src/test/hivemind/test/lib TestEJBProxyFactory.java
               framework/src/test/hivemind/test FrameworkTestCase.java
               framework/src/java/org/apache/hivemind/servlet
                        HiveMindFilter.java
               src/documentation/content HiveMind-QuickReference.doc
  Added:       framework/src/test/org/apache/hivemind/internal/ser
                        Adder.java SerIntegration.xml
                        TestServiceSerializationHelper.java
                        AdderWrapper.java AdderImpl.java
               src/documentation/content/xdocs serializing.xml
               framework/src/java/org/apache/hivemind/internal/ser
                        ServiceSerializationSupport.java SerMessages.java
                        ServiceToken.java SerStrings.properties
                        ServiceSerializationHelper.java package.html
  Log:
  Add ability to serialize service proxies.
  
  Revision  Changes    Path
  1.1                  jakarta-hivemind/framework/src/test/org/apache/hivemind/internal/ser/Adder.java
  
  Index: Adder.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public interface Adder
  {
      public int add(int arg0, int arg1);
  }
  
  
  1.1                  jakarta-hivemind/framework/src/test/org/apache/hivemind/internal/ser/SerIntegration.xml
  
  Index: SerIntegration.xml
  ===================================================================
  <?xml version="1.0"?>
  <module id="test.ser" version="1.0.0">
    
    <service-point id="Adder" interface="org.apache.hivemind.internal.ser.Adder">
      <create-instance class="org.apache.hivemind.internal.ser.AdderImpl"/>
    </service-point>
    
  </module>
  
  
  1.1                  jakarta-hivemind/framework/src/test/org/apache/hivemind/internal/ser/TestServiceSerializationHelper.java
  
  Index: TestServiceSerializationHelper.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  import hivemind.test.FrameworkTestCase;
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.Registry;
  
  /**
   * Tests for {@link org.apache.hivemind.internal.ser.ServiceSerializationHelper}.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class TestServiceSerializationHelper extends FrameworkTestCase
  {
      private ServiceSerializationSupport newSupport()
      {
          return (ServiceSerializationSupport) newMock(ServiceSerializationSupport.class);
      }
  
      public void testGetNoSupport()
      {
          try
          {
              ServiceSerializationHelper.getServiceSerializationSupport();
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertEquals(SerMessages.noSupportSet(), ex.getMessage());
          }
      }
  
      public void testStore()
      {
          ServiceSerializationSupport s = newSupport();
  
          replayControls();
  
          ServiceSerializationHelper.setServiceSerializationSupport(s);
  
          assertSame(s, ServiceSerializationHelper.getServiceSerializationSupport());
  
          verifyControls();
      }
  
      public void testOverwrite()
      {
          ServiceSerializationSupport sa = newSupport();
          ServiceSerializationSupport sb = newSupport();
  
          replayControls();
  
          interceptLogging("org.apache.hivemind.internal.ser");
  
          ServiceSerializationHelper.setServiceSerializationSupport(sa);
          ServiceSerializationHelper.setServiceSerializationSupport(sb);
  
          assertSame(sb, ServiceSerializationHelper.getServiceSerializationSupport());
  
          assertLoggedMessage(SerMessages.supportAlreadySet(sb, sa));
  
          verifyControls();
      }
  
      public void testReset()
      {
          ServiceSerializationSupport s = newSupport();
  
          replayControls();
  
          ServiceSerializationHelper.setServiceSerializationSupport(s);
  
          ServiceSerializationHelper.resetServiceSerializationSupport(s);
  
          try
          {
              ServiceSerializationHelper.getServiceSerializationSupport();
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              // Back to same as never set.
          }
  
          verifyControls();
      }
  
      public void testResetMismatch()
      {
          ServiceSerializationSupport sa = newSupport();
          ServiceSerializationSupport sb = newSupport();
  
          replayControls();
  
          interceptLogging("org.apache.hivemind.internal.ser");
  
          ServiceSerializationHelper.setServiceSerializationSupport(sa);
          ServiceSerializationHelper.setServiceSerializationSupport(sb);
  
          ServiceSerializationHelper.resetServiceSerializationSupport(sa);
  
          assertSame(sb, ServiceSerializationHelper.getServiceSerializationSupport());
  
          verifyControls();
      }
  
      public void testIntegration() throws Exception
      {
          Registry r = buildFrameworkRegistry("SerIntegration.xml");
  
          Adder a = (Adder) r.getService(Adder.class);
  
          AdderWrapper aw1 = new AdderWrapper(a);
  
          byte[] data = serialize(aw1);
  
          AdderWrapper aw2 = (AdderWrapper) deserialize(data);
  
          assertEquals(17, aw2.add(9, 8));
      }
  
      private byte[] serialize(Object o) throws Exception
      {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(bos);
  
          oos.writeObject(o);
  
          oos.close();
  
          return bos.toByteArray();
      }
  
      private Object deserialize(byte[] data) throws Exception
      {
          ByteArrayInputStream bis = new ByteArrayInputStream(data);
          ObjectInputStream ois = new ObjectInputStream(bis);
  
          return ois.readObject();
      }
  }
  
  
  1.1                  jakarta-hivemind/framework/src/test/org/apache/hivemind/internal/ser/AdderWrapper.java
  
  Index: AdderWrapper.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  import java.io.Serializable;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class AdderWrapper implements Serializable
  {
      private Adder _adder;
  
      public AdderWrapper(Adder a)
      {
          _adder = a;
      }
  
      public int add(int arg0, int arg1)
      {
          return _adder.add(arg0, arg1);
      }
  }
  
  
  1.1                  jakarta-hivemind/framework/src/test/org/apache/hivemind/internal/ser/AdderImpl.java
  
  Index: AdderImpl.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class AdderImpl implements Adder
  {
  
      public int add(int arg0, int arg1)
      {
          return arg0 + arg1;
      }
  
  }
  
  
  1.24      +6 -2      jakarta-hivemind/src/documentation/content/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/src/documentation/content/xdocs/index.xml,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- index.xml	19 Dec 2004 15:44:33 -0000	1.23
  +++ index.xml	4 Jan 2005 01:06:22 -0000	1.24
  @@ -90,8 +90,12 @@
           <p>James Carman has just been voted on as a HiveMind committer.</p>
           <p>HiveMind's final 1.0 release occured on Sep 22 2004. Work is already underway 
            on a 1.1 release.</p>
  -        <p>Added the <link href="site:hivemind.lib.AdapterRegistryFactory">AdapterRegistryFactory</link> service implementation
  -          factory.</p>
  +<warning>
  +  This documentation describes HiveMind 1.1, which is currently in an alpha state.
  +  You may <link href="site:downloads">download HiveMind 1.0</link> to get stable
  +  features and matching documentation.
  +</warning>          
  +
   		</section>
       <section>
         <title>Upgrade warnings (release 1.0 to release 1.1)</title>
  
  
  
  1.36      +1 -0      jakarta-hivemind/src/documentation/content/xdocs/site.xml
  
  Index: site.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/src/documentation/content/xdocs/site.xml,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- site.xml	30 Dec 2004 18:55:32 -0000	1.35
  +++ site.xml	4 Jan 2005 01:06:22 -0000	1.36
  @@ -35,6 +35,7 @@
   			<rules label="Contribution Processing Rules" href="rules.html"/>
         <dependencies label="Dependencies" href="dependencies.html"/>
         <conditional label="Conditional Contributions" href="conditional.html"/>
  +      <serial label="Serializing Services" href="serializing.html"/>
    		</reference>
   
       <project-info label="Project Information">
  
  
  
  1.1                  jakarta-hivemind/src/documentation/content/xdocs/serializing.xml
  
  Index: serializing.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
     Copyright 2005 The Apache Software Foundation
  
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
         http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
  -->
  <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN"
  	"http://xml.apache.org/forrest/dtd/document-v13.dtd" [
  	<!ENTITY % common-links SYSTEM "links.ent">
  	%common-links;
  	]>
  <document>
  	<header>
  		<title>Serializing Services</title>
  	</header>
  	<body>
     
  <p> 
  It is often useful, especially in a web-based application,
  to serialize services. In HiveMind 1.0, objects that had references to HiveMind services could not
  be serialized ... the services were not serializable.  You could make your service implemention implement
  Serializable, but that's not what client code sees ... client code sees the service <em>proxy</em>, which
  did not implement Serializable. End of story.
  </p>
  
  <note>
  Service proxies are the objects that are obtained from the Registry, or injected into
  other services.  The proxies implement the service interface, but are generated on the fly.
  These service proxies are part of how HiveMind handles just-in-time service instantiation.
  </note>
  
  <p>
  Starting with HiveMind 1.1, service proxies are, themselves, serializable.  If you create objects that
  have references to HiveMind services, those objects can be serialized.  For example:
  </p>
  
  <source>
  public class MyDataObject implements Serializable
  {
    private MyService _myService;
    
    . . .
  }    
  </source>
  
  <p>
  Here, the <code>MyDataObject</code> class has a reference to a HiveMind service in its
  <code>_myService</code> instance variable. An instance of <code>MyDataObject</code>
  may be serialized in one JVM and de-serialized in another.  In the new JVM, 
  the <code>_myService</code> instance variable will point to an <em>equivalent</em>
  HiveMind service.  
  </p>
  
  <note>
  Serialization involves a particular global static variable that stores the Registry. When a service
  proxy is serialized, the Registry manufactures a <em>service token</em> to take its place. It is this token
  that is actually serialized and deserialized -- not the service proxy itself.
  When the token is later deserialized, it accesses the Registry through the global variable to get 
  the service proxy (in the new JVM) back. This causes a problem if you have multiple Registry instances ... they will
  try to overwrite each other.  If you have multiple web applications that all use HiveMind, you need to ensure
  that the HiveMind framework JARs exist in each WAR's WEB-INF/lib folder ... that will ensure that each
  is loaded by a different class loader, and each will have its own static variable.
  </note>
  
  <p>
  It is the <em>service proxy</em> that is serializable, not the
  <em>service implementation</em>.  That means that a stateful service (one that uses
  the threaded or pooled service model) will likely <strong>not</strong>
  be in the same state in the new JVM.  Again, the internal state of the service is <strong>not</strong>
  serialized ... just the service's id.
  </p>
  
  <p>
  If your service acts as a factory (or otherwise provides access to itself), you must be careful
  to share the service proxy, not the implementation itself.  For example:
  </p>
  
  <source>
  public class MyServiceImpl implements MyService
  {
    private void MyService _myProxy;
    
    public void setMyProxy(MyService myProxy)
    {
      _myProxy = myProxy;
    }
    
    // Service method
    
    public MyDataObject newDataObject()
    {
      return new MyDataObject(_myProxy);
    }
    
    . . .
  }
  </source>
  
  <p>
  Here, the implementation acts as a factory for <code>MyDataObject</code> instances.
  It connects each data object to the service proxy (
  <code>new MyDataObject(_myProxy)</code> rather than <code>new MyDataObject(this)</code>).
  You will need to use the &hivemind.BuilderFactory; and include a &lt;set-service&gt; element to connect 
  the implementation's <code>myProxy</code> property to the service proxy.
  </p>
  
  <p>
  A final note:  Services using the <em>primitive</em> service model do not have
  service proxies and therefore they are <em>not serializable</em>, even in release 1.1. The other service models
  (including the default
  service model, <em>singleton</em>), do use a proxy and are serializable, as discussed in this
  document.
  </p>
  
  </body>
  </document>
  
  
  1.9       +22 -0     jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/ProxyBuilder.java
  
  Index: ProxyBuilder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/ProxyBuilder.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ProxyBuilder.java	9 Nov 2004 20:58:20 -0000	1.8
  +++ ProxyBuilder.java	4 Jan 2005 01:06:22 -0000	1.9
  @@ -14,10 +14,13 @@
   
   package org.apache.hivemind.impl;
   
  +import java.io.ObjectStreamException;
  +import java.io.Serializable;
   import java.lang.reflect.Modifier;
   
   import org.apache.hivemind.internal.Module;
   import org.apache.hivemind.internal.ServicePoint;
  +import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
   import org.apache.hivemind.service.BodyBuilder;
   import org.apache.hivemind.service.ClassFab;
   import org.apache.hivemind.service.ClassFabUtils;
  @@ -61,6 +64,25 @@
                   Object.class);
   
           _classFab.addInterface(_serviceInterface);
  +
  +        addSerializable(point.getExtensionPointId());
  +    }
  +
  +    /** @since 1.1 */
  +    private void addSerializable(String pointId)
  +    {
  +        _classFab.addInterface(Serializable.class);
  +
  +        BodyBuilder bb = new BodyBuilder();
  +
  +        bb.add(
  +                "return {0}.getServiceSerializationSupport().getServiceTokenForService(\"{1}\");",
  +                ServiceSerializationHelper.class.getName(),
  +                pointId);
  +
  +        MethodSignature sig = new MethodSignature(Object.class, "writeReplace", null, null);
  +
  +        _classFab.addMethod(Modifier.PRIVATE, sig, bb.toString());
       }
   
       public ClassFab getClassFab()
  
  
  
  1.6       +57 -1     jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/RegistryInfrastructureImpl.java
  
  Index: RegistryInfrastructureImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/impl/RegistryInfrastructureImpl.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RegistryInfrastructureImpl.java	28 Dec 2004 22:43:14 -0000	1.5
  +++ RegistryInfrastructureImpl.java	4 Jan 2005 01:06:22 -0000	1.6
  @@ -24,6 +24,7 @@
   
   import org.apache.commons.logging.LogFactory;
   import org.apache.hivemind.ApplicationRuntimeException;
  +import org.apache.hivemind.Defense;
   import org.apache.hivemind.ErrorHandler;
   import org.apache.hivemind.HiveMindMessages;
   import org.apache.hivemind.Location;
  @@ -35,6 +36,9 @@
   import org.apache.hivemind.internal.RegistryInfrastructure;
   import org.apache.hivemind.internal.ServiceModelFactory;
   import org.apache.hivemind.internal.ServicePoint;
  +import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
  +import org.apache.hivemind.internal.ser.ServiceSerializationSupport;
  +import org.apache.hivemind.internal.ser.ServiceToken;
   import org.apache.hivemind.order.Orderer;
   import org.apache.hivemind.schema.Translator;
   import org.apache.hivemind.service.ThreadEventNotifier;
  @@ -46,7 +50,8 @@
    * 
    * @author Howard Lewis Ship
    */
  -public final class RegistryInfrastructureImpl implements RegistryInfrastructure
  +public final class RegistryInfrastructureImpl implements RegistryInfrastructure,
  +        ServiceSerializationSupport
   {
       private static final String SYMBOL_SOURCES = "hivemind.SymbolSources";
   
  @@ -74,6 +79,14 @@
       private ShutdownCoordinator _shutdownCoordinator;
   
       /**
  +     * Map of {@link org.apache.hivemind.internal.ser.ServiceToken}, keyed on service id.
  +     * 
  +     * @since 1.1
  +     */
  +
  +    private Map _serviceTokens;
  +
  +    /**
        * Map of {@link ServiceModelFactory}, keyed on service model name, loaded from
        * <code>hivemind.ServiceModels</code> configuration point.
        */
  @@ -294,6 +307,9 @@
       public synchronized void shutdown()
       {
           checkShutdown();
  +
  +        ServiceSerializationHelper.resetServiceSerializationSupport(this);
  +
           // Allow service implementations and such to shutdown.
   
           ShutdownCoordinator coordinatorService = (ShutdownCoordinator) getService(
  @@ -316,6 +332,7 @@
           _variableSources = null;
           _serviceModelFactories = null;
           _threadEventNotifier = null;
  +        _serviceTokens = null;
   
           // It is believed that the cache held by PropertyUtils can affect application shutdown
           // and reload in some servlet containers (such as Tomcat); this should clear that up.
  @@ -340,6 +357,10 @@
        * locks down the Registry so that no further extension points may be added. This method may
        * only be invoked once.
        * <p>
  +     * This instance is stored into
  +     * {@link ServiceSerializationHelper#setServiceSerializationSupport(ServiceSerializationSupport)}.
  +     * This may cause errors (and incorrect behavior) if multiple Registries exist in a single JVM.
  +     * <p>
        * In addition, the service <code>hivemind.Startup</code> is obtained and <code>run()</code>
        * is invoked on it. This allows additional startup, provided in the
        * <code>hivemind.Startup</code> configuration point, to be executed.
  @@ -348,6 +369,8 @@
       {
           checkStarted();
   
  +        ServiceSerializationHelper.setServiceSerializationSupport(this);
  +
           _started = true;
   
           Runnable startup = (Runnable) getService("hivemind.Startup", Runnable.class, null);
  @@ -452,5 +475,38 @@
       public Translator getTranslator(String translator)
       {
           return _translatorManager.getTranslator(translator);
  +    }
  +
  +    public Object getServiceFromToken(ServiceToken token)
  +    {
  +        Defense.notNull(token, "token");
  +
  +        checkShutdown();
  +
  +        String serviceId = token.getServiceId();
  +
  +        ServicePoint sp = (ServicePoint) _servicePoints.get(serviceId);
  +
  +        return sp.getService(Object.class);
  +    }
  +
  +    public synchronized ServiceToken getServiceTokenForService(String serviceId)
  +    {
  +        Defense.notNull(serviceId, "serviceId");
  +
  +        checkShutdown();
  +
  +        if (_serviceTokens == null)
  +            _serviceTokens = new HashMap();
  +
  +        ServiceToken result = (ServiceToken) _serviceTokens.get(serviceId);
  +
  +        if (result == null)
  +        {
  +            result = new ServiceToken(serviceId);
  +            _serviceTokens.put(serviceId, result);
  +        }
  +
  +        return result;
       }
   }
  
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/ServiceSerializationSupport.java
  
  Index: ServiceSerializationSupport.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  /**
   * Utility interface used to support serialization of services (really, service proxies).
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public interface ServiceSerializationSupport
  {
      /**
       * Returns a {@link ServiceToken}corresponding to the indicated serviceId. A ServiceToken takes
       * the place of a service (proxy) during serialization.
       */
  
      public ServiceToken getServiceTokenForService(String serviceId);
  
      /**
       * Returns the service (proxy) for the indicated token.
       */
  
      public Object getServiceFromToken(ServiceToken token);
  }
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/SerMessages.java
  
  Index: SerMessages.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  import org.apache.hivemind.impl.MessageFormatter;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  class SerMessages
  {
      private static final MessageFormatter _formatter = new MessageFormatter(SerMessages.class,
              "SerStrings");
  
      public static String noSupportSet()
      {
          return _formatter.getMessage("no-support-set");
      }
  
      public static String supportAlreadySet(Object newSupport, Object oldSupport)
      {
          return _formatter.format("support-already-set", newSupport, oldSupport);
      }
  }
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/ServiceToken.java
  
  Index: ServiceToken.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  import java.io.Externalizable;
  import java.io.IOException;
  import java.io.ObjectInput;
  import java.io.ObjectOutput;
  import java.io.ObjectStreamException;
  
  import org.apache.hivemind.Defense;
  
  /**
   * Instance used to replace actual service (proxies) during serialization. Note that this represents
   * a back-door into HiveMind's {@link org.apache.hivemind.internal.RegistryInfrastructure}, which
   * is less than ideal, and should not be used by end-user code!
   * 
   * @author Howard M. Lewis Ship
   */
  public class ServiceToken implements Externalizable
  {
      private String _serviceId;
  
      // Needed for Externalizable.
  
      public ServiceToken()
      {
      }
  
      public ServiceToken(String serviceId)
      {
          Defense.notNull(serviceId, "serviceId");
  
          _serviceId = serviceId;
      }
  
      public String getServiceId()
      {
          return _serviceId;
      }
  
      public void writeExternal(ObjectOutput out) throws IOException
      {
          out.writeUTF(_serviceId);
      }
  
      public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
      {
          _serviceId = in.readUTF();
      }
  
      Object readResolve()
      {
          return ServiceSerializationHelper.getServiceSerializationSupport()
                  .getServiceFromToken(this);
      }
  }
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/SerStrings.properties
  
  Index: SerStrings.properties
  ===================================================================
  #
  # Copyright 2004 The Apache Software Foundation
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  no-support-set=The ServiceSerializationSupport instance has not been set; this indicates that the HiveMind Registry has not been created within this JVM.
  support-already-set=Replacing ServiceSerializationSupport instance {0} with {1}; this indicates that multiple HiveMind Registies have been created, and conflicts may occur.
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/ServiceSerializationHelper.java
  
  Index: ServiceSerializationHelper.java
  ===================================================================
  package org.apache.hivemind.internal.ser;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.hivemind.ApplicationRuntimeException;
  
  /**
   * Class used to hold a <em>global</em> instance of
   * {@link org.apache.hivemind.internal.ser.ServiceSerializationSupport}, so that
   * {@link org.apache.hivemind.internal.ser.ServiceToken}s may locate them.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class ServiceSerializationHelper
  {
      private static final Log LOG = LogFactory.getLog(ServiceSerializationHelper.class);
  
      private static ServiceSerializationSupport _serviceSerializationSupport;
  
      /**
       * Returns the previously stored SSS.
       * 
       * @throws ApplicationRuntimeException
       *             if no SSS has been stored.
       */
      public static ServiceSerializationSupport getServiceSerializationSupport()
      {
          if (_serviceSerializationSupport == null)
              throw new ApplicationRuntimeException(SerMessages.noSupportSet());
  
          return _serviceSerializationSupport;
      }
  
      /**
       * Stores the SSS instance for later access; if an existing SSS is already stored, then an error
       * is logged (should be just one SSS per class loader).
       */
  
      public static void setServiceSerializationSupport(
              ServiceSerializationSupport serviceSerializationSupport)
      {
          if (serviceSerializationSupport != null && _serviceSerializationSupport != null)
              LOG.error(SerMessages.supportAlreadySet(
                      serviceSerializationSupport,
                      _serviceSerializationSupport));
  
          _serviceSerializationSupport = serviceSerializationSupport;
      }
  
      /**
       * Invoked to clear the SSS, if it matches the provide parameter. This is necessary, rather than
       * blindly setting it to null, because of a tricky case related to
       * {@link org.apache.hivemind.servlet.HiveMindFilter}, which includes the ability to create a
       * new Registry on the fly and has to leave both Registry's running for a brief window.
       */
  
      public static void resetServiceSerializationSupport(
              ServiceSerializationSupport serviceSerializationSupport)
      {
          if (_serviceSerializationSupport == serviceSerializationSupport)
              _serviceSerializationSupport = null;
      }
  
  }
  
  
  1.1                  jakarta-hivemind/framework/src/java/org/apache/hivemind/internal/ser/package.html
  
  Index: package.html
  ===================================================================
  <!-- 
     Copyright 2004 The Apache Software Foundation
  
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
         http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
  -->
  
  <body>
  
  Serialization of services.
  
  </body>
  
  
  1.7       +1 -1      jakarta-hivemind/forrest.properties
  
  Index: forrest.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/forrest.properties,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- forrest.properties	19 Nov 2004 20:28:49 -0000	1.6
  +++ forrest.properties	4 Jan 2005 01:06:22 -0000	1.7
  @@ -17,7 +17,7 @@
   
   forrest.echo=on
   project.debuglevel=DEBUG
  -project.bugtracking-url=http://nagoya.apache.org/jira/browse/
  +project.bugtracking-url=http://issues.apache.org/jira/browse/
   
   project.configfile=${project.home}/src/documentation/conf/cli.xconf
   
  
  
  
  1.89      +4 -0      jakarta-hivemind/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/status.xml,v
  retrieving revision 1.88
  retrieving revision 1.89
  diff -u -r1.88 -r1.89
  --- status.xml	30 Dec 2004 18:55:32 -0000	1.88
  +++ status.xml	4 Jan 2005 01:06:22 -0000	1.89
  @@ -130,6 +130,10 @@
        <action type="add" dev="HLS">
         Add support for conditional contributions.
        </action>
  +      <action type="add" dev="HLS">
  +        Allow services to be serialized (that is, service proxies can be serialized and
  +        deserialized).
  +      </action>     
       </release>
   
      <release version="1.0" date="Sep 22 2004">
  
  
  
  1.21      +3 -0      jakarta-hivemind/framework/src/java/org/apache/hivemind/test/HiveMindTestCase.java
  
  Index: HiveMindTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/test/HiveMindTestCase.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- HiveMindTestCase.java	28 Dec 2004 22:43:15 -0000	1.20
  +++ HiveMindTestCase.java	4 Jan 2005 01:06:22 -0000	1.21
  @@ -33,6 +33,7 @@
   import org.apache.hivemind.impl.LocationImpl;
   import org.apache.hivemind.impl.RegistryBuilder;
   import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
  +import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
   import org.apache.hivemind.util.ClasspathResource;
   import org.apache.hivemind.util.PropertyUtils;
   import org.apache.hivemind.util.URLResource;
  @@ -220,6 +221,8 @@
           }
   
           PropertyUtils.clearCache();
  +
  +        ServiceSerializationHelper.setServiceSerializationSupport(null);
       }
   
       /**
  
  
  
  1.6       +13 -10    jakarta-hivemind/library/src/test/hivemind/test/lib/TestEJBProxyFactory.java
  
  Index: TestEJBProxyFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/library/src/test/hivemind/test/lib/TestEJBProxyFactory.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestEJBProxyFactory.java	25 Jun 2004 20:20:00 -0000	1.5
  +++ TestEJBProxyFactory.java	4 Jan 2005 01:06:22 -0000	1.6
  @@ -1,4 +1,4 @@
  -//  Copyright 2004 The Apache Software Foundation
  +// Copyright 2004 The Apache Software Foundation
   //
   // Licensed under the Apache License, Version 2.0 (the "License");
   // you may not use this file except in compliance with the License.
  @@ -46,8 +46,9 @@
           context.bind("hivemind.test.lib.Simple", home);
           NameLookupHack._context = context;
   
  -        SimpleRemote object =
  -            (SimpleRemote) r.getService("hivemind.test.lib.SimpleRemote", SimpleRemote.class);
  +        SimpleRemote object = (SimpleRemote) r.getService(
  +                "hivemind.test.lib.SimpleRemote",
  +                SimpleRemote.class);
   
           assertEquals(7, object.add(4, 3));
           // Exercise several code paths where objects are ready or cached.
  @@ -72,8 +73,9 @@
   
           NameLookupHack._context = context;
   
  -        SimpleRemote object =
  -            (SimpleRemote) r.getService("hivemind.test.lib.SimpleRemote", SimpleRemote.class);
  +        SimpleRemote object = (SimpleRemote) r.getService(
  +                "hivemind.test.lib.SimpleRemote",
  +                SimpleRemote.class);
   
           try
           {
  @@ -84,8 +86,8 @@
           catch (ApplicationRuntimeException ex)
           {
               assertExceptionSubstring(
  -                ex,
  -                "Unable to lookup 'hivemind.test.lib.Simple' in JNDI context");
  +                    ex,
  +                    "Unable to lookup 'hivemind.test.lib.Simple' in JNDI context");
   
               Throwable t = findNestedException(ex);
   
  @@ -106,8 +108,9 @@
   
           NameLookupHack._context = context;
   
  -        SimpleRemote object =
  -            (SimpleRemote) r.getService("hivemind.test.lib.SimpleRemote", SimpleRemote.class);
  +        SimpleRemote object = (SimpleRemote) r.getService(
  +                "hivemind.test.lib.SimpleRemote",
  +                SimpleRemote.class);
   
           try
           {
  @@ -121,4 +124,4 @@
           }
       }
   
  -}
  +}
  \ No newline at end of file
  
  
  
  1.18      +6 -6      jakarta-hivemind/framework/src/test/hivemind/test/FrameworkTestCase.java
  
  Index: FrameworkTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/FrameworkTestCase.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- FrameworkTestCase.java	16 Nov 2004 10:27:12 -0000	1.17
  +++ FrameworkTestCase.java	4 Jan 2005 01:06:22 -0000	1.18
  @@ -18,6 +18,7 @@
   import org.apache.hivemind.Resource;
   import org.apache.hivemind.impl.DefaultClassResolver;
   import org.apache.hivemind.impl.DefaultErrorHandler;
  +import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
   import org.apache.hivemind.parse.ConfigurationPointDescriptor;
   import org.apache.hivemind.parse.DependencyDescriptor;
   import org.apache.hivemind.parse.ModuleDescriptor;
  @@ -27,7 +28,7 @@
   
   /**
    * Base class for framework tests.
  - *
  + * 
    * @author Howard Lewis Ship
    */
   public abstract class FrameworkTestCase extends HiveMindTestCase
  @@ -64,7 +65,7 @@
       protected ModuleDescriptor createModuleDescriptor(String moduleId, String version)
       {
           ModuleDescriptor result = new ModuleDescriptor(_resolver, new DefaultErrorHandler());
  -    
  +
           result.setModuleId(moduleId);
           result.setVersion(version);
           result.setLocation(fabricateLocation(0));
  @@ -78,11 +79,11 @@
       protected DependencyDescriptor createDependencyDescriptor(String moduleId, String version)
       {
           DependencyDescriptor result = new DependencyDescriptor();
  -    
  +
           result.setModuleId(moduleId);
           result.setVersion(version);
           result.setLocation(fabricateLocation(0));
  -    
  +
           return result;
       }
   
  @@ -113,5 +114,4 @@
   
           return result;
       }
  -
  -}
  +}
  \ No newline at end of file
  
  
  
  1.16      +11 -9     jakarta-hivemind/framework/src/java/org/apache/hivemind/servlet/HiveMindFilter.java
  
  Index: HiveMindFilter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/servlet/HiveMindFilter.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- HiveMindFilter.java	22 Dec 2004 00:11:02 -0000	1.15
  +++ HiveMindFilter.java	4 Jan 2005 01:06:22 -0000	1.16
  @@ -34,6 +34,7 @@
   import org.apache.hivemind.impl.DefaultClassResolver;
   import org.apache.hivemind.impl.RegistryBuilder;
   import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
  +import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
   import org.apache.hivemind.util.ContextResource;
   
   /**
  @@ -109,6 +110,12 @@
   
           addWebInfDescriptor(config.getServletContext(), resolver, builder);
   
  +        // This avoids an error message when replacing the SSS (really, the RegistryInfrastructure).
  +        // HiveMindFilter's reload-the-registry functionality is an exception to the rule
  +        // that there should just be one Registry per JVM.
  +
  +        ServiceSerializationHelper.setServiceSerializationSupport(null);
  +
           return builder.constructRegistry(getRegistryLocale());
       }
   
  @@ -179,15 +186,6 @@
           if (request.getAttribute(REBUILD_REQUEST_KEY) == null)
               return;
   
  -        // This is so not threadsafe, but you don't do this very often.
  -        // This method is synchronized, but other threads may be actively using
  -        // the Registry we're shutting down.
  -
  -        // What we really need is some good concurrence support to track the number
  -        // of threads that may be using the old registry, set a write lock, and wait
  -        // for that number to drop to one (this thread). Instead, we'll just swap in the
  -        // new Registry and hope for the best.
  -
           Registry oldRegistry = _registry;
   
           // Replace the old Registry with a new one. All other threads, but this
  @@ -199,6 +197,10 @@
           // Shutdown the old Registry. Perhaps we should sleep for a moment, first,
           // to help ensure that other threads have "cleared out". If not, we'll see some
           // instability at the instant we shutdown (i.e., all the proxies will get disabled).
  +        // Alternately, we should create a WeakReference based monitor that shuts down the
  +        // old registry when it is no longer used by any other threads. For the moment,
  +        // this functionality is limited to development-time only (not production), so it isn't
  +        // urgent.
   
           oldRegistry.shutdown();
       }
  
  
  
  1.2       +72 -66    jakarta-hivemind/src/documentation/content/HiveMind-QuickReference.doc
  
  	<<Binary file>>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-cvs-help@jakarta.apache.org