[jboss-cvs] JBossAS SVN: r77666 - in trunk: cluster/src/etc and 8 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Aug 29 18:16:14 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-08-29 18:16:14 -0400 (Fri, 29 Aug 2008)
New Revision: 77666

Added:
   trunk/cluster/src/etc/hajndi-jboss-beans.xml
   trunk/cluster/src/main/org/jboss/ha/jndi/impl/
   trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/
   trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManager.java
   trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManagerMBean.java
   trunk/cluster/src/main/org/jboss/ha/jndi/spi/
   trunk/cluster/src/main/org/jboss/ha/jndi/spi/DistributedTreeManager.java
Removed:
   trunk/cluster/src/etc/hajndi-service.xml
   trunk/cluster/src/main/org/jboss/ha/jndi/TreeHead.java
Modified:
   trunk/build/build-distr.xml
   trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java
   trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingServiceMBean.java
   trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java
   trunk/testsuite/src/resources/cluster/ejb2/passexp/META-INF/partition-passexp-jboss-beans.xml
   trunk/testsuite/src/resources/cluster/ejb2/passexp/partition-passexp-service.xml
   trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml
   trunk/testsuite/src/resources/cluster/partition/partition-restart-service.xml
   trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml
Log:
[JBAS-5914] Convert HAJNDI back to -jboss-beans.xml

Modified: trunk/build/build-distr.xml
===================================================================
--- trunk/build/build-distr.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/build/build-distr.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -995,7 +995,7 @@
       <fileset dir="${_module.output}/etc">
         <include name="cluster-jboss-beans.xml"/>
         <include name="deploy-hasingleton-jboss-beans.xml"/>
-        <include name="hajndi-service.xml"/>
+        <include name="hajndi-jboss-beans.xml"/>
         <include name="ha-legacy-service.xml"/>
       </fileset>
     </copy>

Copied: trunk/cluster/src/etc/hajndi-jboss-beans.xml (from rev 77655, trunk/cluster/src/etc/hajndi-service.xml)
===================================================================
--- trunk/cluster/src/etc/hajndi-jboss-beans.xml	                        (rev 0)
+++ trunk/cluster/src/etc/hajndi-jboss-beans.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ===================================================================== -->
+<!--                                                                       -->
+<!--  HA-JNDI Service Configuration                                        -->
+<!--                                                                       -->
+<!-- ===================================================================== -->
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+   
+   <bean name="HAJNDI"
+         class="org.jboss.ha.jndi.HANamingService">    
+
+      <depends>jboss:service=Naming</depends>
+      
+      <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss:service=HAJNDI", exposedInterface=org.jboss.ha.jndi.HANamingServiceMBean.class)</annotation>
+           
+      
+      <!-- The partition used for group RPCs to find locally bound objects on other nodes -->
+      <property name="HAPartition"><inject bean="HAPartition"/></property>
+      
+      <!-- Handler for the replicated tree -->
+      <property name="distributedTreeManager">
+         <bean class="org.jboss.ha.jndi.impl.jbc.JBossCacheDistributedTreeManager">
+            <property name="clusteredCache"><inject bean="HAPartition" property="clusteredCache"/></property>
+         </bean>
+      </property>
+      
+      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
+      <property name="lookupPool"><inject bean="jboss.system:service=ThreadPool"/></property>
+      
+      <!-- Bind address of bootstrap endpoint -->
+      <property name="bindAddress">${jboss.bind.address}</property>
+      <!-- Port on which the HA-JNDI stub is made available -->
+      <property name="port">
+         <!-- Get the port from the ServiceBindingManager -->
+         <value-factory bean="ServiceBindingManager" method="getIntBinding">
+            <parameter>jboss:service=HAJNDI</parameter>
+            <parameter>Port</parameter>
+         </value-factory>
+      </property>
+      
+      <!-- Bind address of the HA-JNDI RMI endpoint -->
+      <property name="rmiBindAddress">${jboss.bind.address}</property>
+      
+      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
+      <property name="rmiPort">
+         <!-- Get the port from the ServiceBindingManager -->
+         <value-factory bean="ServiceBindingManager" method="getIntBinding">
+            <parameter>jboss:service=HAJNDI</parameter>
+            <parameter>RmiPort</parameter>
+         </value-factory>
+      </property>
+      
+      <!-- Accept backlog of the bootstrap socket -->
+      <property name="backlog">50</property>
+
+      <!-- A flag to disable the auto discovery via multicast -->
+      <property name="discoveryDisabled">false</property>
+      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
+      specified and a BindAddress is specified, the BindAddress will be used. -->
+      <property name="autoDiscoveryBindAddress">${jboss.bind.address}</property>
+      <!-- Multicast Address and group port used for auto-discovery -->
+      <property name="autoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</property>
+      <property name="autoDiscoveryGroup">1102</property>
+      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
+      <property name="autoDiscoveryTTL">16</property>
+      
+      <!-- The load balancing policy for HA-JNDI -->
+      <property name="loadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</property>
+
+      <!-- Client socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="clientSocketFactory">custom</property>
+      -->
+      <!-- Server socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="serverSocketFactory">custom</property>
+      -->
+   </bean>
+
+</deployment>

Deleted: trunk/cluster/src/etc/hajndi-service.xml
===================================================================
--- trunk/cluster/src/etc/hajndi-service.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/cluster/src/etc/hajndi-service.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- ===================================================================== -->
-<!--                                                                       -->
-<!--  HA-JNDI Service Configuration                                        -->
-<!--                                                                       -->
-<!-- ===================================================================== -->
-
-<server>
-   
-   <mbean code="org.jboss.ha.jndi.HANamingService"
-      name="jboss:service=HAJNDI">      
-      
-      <!-- The partition used for group RPCs to find locally bound objects -->
-      <attribute name="HAPartition"><inject bean="HAPartition"/></attribute>
-      <!-- The cache for storing the replicated tree  -->
-      <attribute name="ClusteredCache"><inject bean="HAPartition" property="clusteredCache"/></attribute>
-      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
-      <attribute name="LookupPool"><inject bean="jboss.system:service=ThreadPool"/></attribute>
-      
-      <!-- Bind address of bootstrap endpoint -->
-      <attribute name="BindAddress">${jboss.bind.address}</attribute>
-      <!-- Port on which the HA-JNDI stub is made available -->
-      <attribute name="Port">
-         <!-- Get the port from the ServiceBindingManager -->
-         <value-factory bean="ServiceBindingManager" method="getIntBinding">
-            <parameter>jboss:service=HAJNDI</parameter>
-            <parameter>Port</parameter>
-         </value-factory>
-      </attribute>
-      
-      <!-- Bind address of the HA-JNDI RMI endpoint -->
-      <attribute name="RmiBindAddress">${jboss.bind.address}</attribute>
-      
-      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
-      <attribute name="RmiPort">
-         <!-- Get the port from the ServiceBindingManager -->
-         <value-factory bean="ServiceBindingManager" method="getIntBinding">
-            <parameter>jboss:service=HAJNDI</parameter>
-            <parameter>RmiPort</parameter>
-         </value-factory>
-      </attribute>
-      
-      <!-- Accept backlog of the bootstrap socket -->
-      <attribute name="Backlog">50</attribute>
-
-      <!-- A flag to disable the auto discovery via multicast -->
-      <attribute name="DiscoveryDisabled">false</attribute>
-      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
-      specified and a BindAddress is specified, the BindAddress will be used. -->
-      <attribute name="AutoDiscoveryBindAddress">${jboss.bind.address}</attribute>
-      <!-- Multicast Address and group port used for auto-discovery -->
-      <attribute name="AutoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</attribute>
-      <attribute name="AutoDiscoveryGroup">1102</attribute>
-      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
-      <attribute name="AutoDiscoveryTTL">16</attribute>
-      <!-- The load balancing policy for HA-JNDI -->
-      <attribute name="LoadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</attribute>
-
-      <!-- Client socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ClientSocketFactory">custom</attribute>
-      -->
-      <!-- Server socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ServerSocketFactory">custom</attribute>
-      -->
-   </mbean>
-
-</server>

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -1,24 +1,24 @@
 /*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
 package org.jboss.ha.jndi;
 
 import java.io.IOException;
@@ -43,12 +43,11 @@
 import javax.management.ObjectName;
 import javax.management.Query;
 import javax.management.QueryExp;
-import javax.naming.Binding;
 import javax.net.ServerSocketFactory;
 
-import org.jboss.cache.Cache;
 import org.jboss.ha.framework.interfaces.HAPartition;
 import org.jboss.ha.framework.server.ClusterPartitionMBean;
+import org.jboss.ha.jndi.spi.DistributedTreeManager;
 import org.jboss.invocation.Invocation;
 import org.jboss.invocation.MarshalledInvocation;
 import org.jboss.logging.Logger;
@@ -98,9 +97,9 @@
     */
    protected HAPartition clusterPartition;
    /**
-    * The cache used to store HA-JNDI bindings
+    * The manager of our distributed bindings
     */
-   private Cache<String, Binding> cache;
+   private DistributedTreeManager  distributedTreeManager;
 
    /**
     * The proxy factory service that generates the Naming stub
@@ -186,14 +185,14 @@
       this.clusterPartition = clusterPartition;
    }
    
-   public Cache<String, Binding> getClusteredCache()
+   public DistributedTreeManager  getDistributedTreeManager ()
    {
-      return this.cache;
+      return this.distributedTreeManager;
    }
 
-   public void setClusteredCache(Cache<String, Binding> cache)
+   public void setDistributedTreeManager (DistributedTreeManager  distributedTreeManager )
    {
-      this.cache = cache;
+      this.distributedTreeManager = distributedTreeManager;
    }
 
    public ObjectName getProxyFactoryObjectName()
@@ -322,15 +321,15 @@
          throw new IllegalStateException("HAPartition property must be set before starting HAJNDI service");
       }
       
-      if (this.cache == null)
+      if (this.distributedTreeManager == null)
       {
-         throw new IllegalStateException("ClusteredCache property must be set before starting HAJNDI service");
+         throw new IllegalStateException("DistributedTreeManager property must be set before starting HAJNDI service");
       }
       
       this.log.debug("Initializing HAJNDI server on partition: " + this.clusterPartition.getPartitionName());
       
       // Start HAJNDI service
-      this.theServer = new HAJNDI(this.clusterPartition, this.cache);
+      this.theServer = new HAJNDI(this.clusterPartition, this.distributedTreeManager);
 
       // Build the Naming interface method map
       Map<Long, Method> map = new HashMap<Long, Method>(13);
@@ -352,7 +351,7 @@
    {
       this.log.debug("Obtaining the HAJNDI transport proxy");
       this.stub = this.getNamingProxy();
-      this.theServer.setHAStub(this.stub);
+      this.distributedTreeManager.setHAStub(this.stub);
       if (this.port >= 0)
       {
          this.log.debug("Starting HAJNDI bootstrap listener");
@@ -394,7 +393,7 @@
 
       // Stop HAJNDI service
       this.log.debug("Stopping the HAJNDI service");
-      this.theServer.stop();
+      this.theServer.shutdown();
 
       this.log.debug("Stopping AutomaticDiscovery");
       if (this.autoDiscovery != null && this.discoveryDisabled == false)
@@ -406,12 +405,7 @@
    @Override
    protected void destroyService() throws Exception
    {
-      this.log.debug("Destroying the HAJNDI service");
-      // server may be null if service failed on startup
-      if (this.theServer != null)
-      {
-         this.theServer.destroy();
-      }
+      this.log.debug("Destroying the HAJNDI service");      
    }
 
    /**

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingServiceMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingServiceMBean.java	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingServiceMBean.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -29,6 +29,7 @@
 
 import org.jboss.cache.Cache;
 import org.jboss.ha.framework.interfaces.HAPartition;
+import org.jboss.ha.jndi.spi.DistributedTreeManager;
 import org.jboss.invocation.Invocation;
 import org.jboss.util.threadpool.BasicThreadPoolMBean;
 
@@ -65,18 +66,18 @@
    void setHAPartition(HAPartition clusterPartition);
    
    /**
-    * Get the underlying cache used by this service.
+    * Get the DistributedTreeManager used by this service.
     * 
     * @return the cache
     */
-   Cache<String, Binding> getClusteredCache();
+   DistributedTreeManager getDistributedTreeManager();
    
    /**
-    * Sets the underlying cache used by this service.
+    * Sets the DistributedTreeManager used by this service.
     * 
     * @param cache the cache
     */
-   void setClusteredCache(Cache<String, Binding> cache);
+   void setDistributedTreeManager (DistributedTreeManager distributedTreeManager);
 
    /** Get the proxy factory service name used to create the Naming transport
     * proxy.

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -22,84 +22,135 @@
 package org.jboss.ha.jndi;
 
 import java.util.Collection;
+import java.util.List;
 
 import javax.naming.Binding;
+import javax.naming.InitialContext;
 import javax.naming.Name;
 import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
 
-import org.jboss.cache.Cache;
-import org.jboss.cache.Fqn;
 import org.jboss.ha.framework.interfaces.HAPartition;
-import org.jnp.interfaces.Naming;
+import org.jboss.ha.jndi.spi.DistributedTreeManager;
+import org.jboss.logging.Logger;
+import org.jnp.interfaces.NamingContext;
 
 /**
- *  This class utilizes JBossCache to provide a distributed JNDI implementation.
- *  Lookups will look for Names in HAJNDI then delegate to the local InitialContext.
+ *  Provides the Naming implemenation. Lookups will look for Names in 
+ *  the injected DistributedTreeManager and if not found will delegate to the local 
+ *  InitialContext. If still not found, a group RPC will be sent to the cluster
+ *  using the provided partition.  All other Naming operations delegate to the 
+ *  DistributedTreeManager.
  *
  *  @author <a href="mailto:bill at burkecentral.com">Bill Burke</a>
  *  @author Scott.Stark at jboss.org
+ *  @author Brian Stansberry
+ *  
  *  @version $Revision$
  */
 public class HAJNDI
    implements org.jnp.interfaces.Naming
 {
+   private static final Logger log = Logger.getLogger(HAJNDI.class);
+   
    /** @since 1.12.2.4, jboss-3.2.2 */
    static final long serialVersionUID = -6277328603304171620L;
-  
-   public static final String ROOT = "__HA_JNDI__";
-   public static final Fqn<String> ROOTFQN = new Fqn<String>(ROOT);
    
    // Attributes --------------------------------------------------------
-   private HAPartition partition;
-   private TreeHead delegate;
-   private Naming haStub;
+   
+   private final HAPartition partition;
+   private final DistributedTreeManager delegate;
 
    // Constructor --------------------------------------------------------
   
-   public HAJNDI(HAPartition partition, Cache<String, Binding> cache)
+   public HAJNDI(HAPartition partition, DistributedTreeManager delegate)
    {
       if (partition == null)
       {
          throw new IllegalArgumentException("Null partition");
       }
       
-      if (cache == null)
+      if (delegate == null)
       {
-         throw new IllegalArgumentException("Null cache");
+         throw new IllegalArgumentException("Null delegate");
       }
       
       this.partition = partition;
-      this.delegate = new TreeHead(cache, HAJNDI.ROOTFQN);
-      this.delegate.setPartition(this.partition);
-      this.delegate.setHARMIHead(this);
+      this.delegate = delegate;
    }
    
    // Public --------------------------------------------------------
 
    public void init()
    {
+      log.debug("HAJNDI registering RPC Handler with HAPartition");
+      this.partition.registerRPCHandler("HAJNDI", this);
       this.delegate.init();
    }
 
-   public void stop()
+   public void shutdown()
    {
-      this.delegate.stop();
+      log.debug("HAJNDI unregistering RPCHandler with HAPartition");
+      this.partition.unregisterRPCHandler("HAJNDI", this);
+      this.delegate.shutdown();
    }
 
-   public void destroy()
+   /**
+    * Performs a lookup against the local Naming service. This method is only
+    * public so HAPartition can invoke on it via reflection.
+    * 
+    * @param name the name
+    * @return     the object bound locally under name
+    * @throws NamingException
+    */
+   public Object lookupLocally(Name name) throws NamingException
    {
-      this.delegate.destroy();
-   }
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+      {
+         log.trace("lookupLocally, name="+name);
+      }
 
-   public void setHAStub(Naming stub)
-   {
-      this.haStub = stub;
-   }
+      // TODO: This is a really big hack here
+      // We cannot do InitialContext().lookup(name) because
+      // we get ClassNotFound errors and ClassLinkage errors.
+      // So, what we do is cheat and get the static localServer variable
+      try
+      {
+         if (NamingContext.localServer != null)
+         {
+            return NamingContext.localServer.lookup(name);
+         }
 
-   public Naming getHAStub()
-   {
-      return this.haStub;
+         return new InitialContext().lookup(name);
+      }
+      catch (NamingException e)
+      {
+         if (trace)
+         {
+            log.trace("lookupLocally failed, name=" + name, e);
+         }
+         throw e;
+      }
+      catch (java.rmi.RemoteException e)
+      {
+         NamingException ne = new NamingException("unknown remote exception");
+         ne.setRootCause(e);
+         if( trace )
+         {
+            log.trace("lookupLocally failed, name=" + name, e);
+         }
+         throw ne;
+      }
+      catch (RuntimeException e)
+      {
+         if (trace)
+         {
+            log.trace("lookupLocally failed, name=" + name, e);
+         }
+         throw e;
+      }
    }
 
    // Naming implementation -----------------------------------------
@@ -122,7 +173,23 @@
 
    public Object lookup(Name name) throws NamingException
    {
-      return this.delegate.lookup(name);
+      Object binding = this.delegate.lookup(name);
+      if (binding == null)
+      {
+         try
+         {
+            binding = lookupLocally(name);
+         }
+         catch (NameNotFoundException nne)
+         {
+            binding = lookupRemotely(name);
+            if (binding == null)
+            {
+               throw nne;
+            }
+         }
+      }
+      return binding;
    }
 
    public Collection<NameClassPair> list(Name name) throws NamingException
@@ -139,4 +206,61 @@
    {
       return this.delegate.createSubcontext(name);
    }
+   
+   // ----------------------------------------------------------------  Private
+   
+   private Object lookupRemotely(Name name) throws NameNotFoundException
+   {
+      boolean trace = log.isTraceEnabled();
+      
+      // if we get here, this means we need to try on every node.
+      Object[] args = new Object[1];
+      args[0] = name;
+      List<?> rsp = null;
+      Exception cause = null;
+      try
+      {
+         if (trace)
+         {
+            log.trace("calling lookupLocally(" + name + ") on HAJNDI cluster");
+         }
+         rsp = this.partition.callMethodOnCluster("HAJNDI", "lookupLocally", args, new Class[] { Name.class }, true);
+      }
+      catch (Exception ignored)
+      {
+         if (trace)
+         {
+            log.trace("Clustered lookupLocally("+name+") failed", ignored);
+         }
+         cause = ignored;
+      }
+
+      if (trace)
+      {
+         log.trace("Returned results size: "+ (rsp != null ? rsp.size() : 0));
+      }
+      if (rsp == null || rsp.size() == 0)
+      {
+         NameNotFoundException nnfe2 = new NameNotFoundException(name.toString());
+         nnfe2.setRootCause(cause);
+         throw nnfe2;
+      }
+
+      for (int i = 0; i < rsp.size(); i++)
+      {
+         Object result = rsp.get(i);
+         if (trace)
+         {
+            String type = (result != null ? result.getClass().getName() : "null");
+            log.trace("lookupLocally, i="+i+", value="+result+", type="+type);
+         }
+         // Ignore null and Exception return values
+         if ((result != null) && !(result instanceof Exception))
+         {
+            return result;
+         }
+      }
+      
+      return null;
+   }
 }

Deleted: trunk/cluster/src/main/org/jboss/ha/jndi/TreeHead.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/TreeHead.java	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/TreeHead.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -1,646 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.ha.jndi;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.Binding;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.InvalidNameException;
-import javax.naming.Name;
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.NameClassPair;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import javax.naming.NotContextException;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.ha.framework.interfaces.HAPartition;
-import org.jboss.logging.Logger;
-import org.jnp.interfaces.Naming;
-import org.jnp.interfaces.NamingContext;
-import org.jnp.interfaces.NamingParser;
-
-/**
- *  This class utilizes JBossCache to provide a distributed JNDI implementation.
- *  Lookups will look for Names in HAJNDI then delegate to the local InitialContext.
- *
- *  @author <a href="mailto:jgauthier at novell.com">Jerry Gauthier</a>
- *  @version $Revision$
- */
-public class TreeHead
-   implements org.jnp.interfaces.Naming
-{
-   static final long serialVersionUID = 6342802270002172451L;
-
-   private static final NamingParser parser = new NamingParser();
-   private final Fqn<String> m_root;
-   
-   // Attributes --------------------------------------------------------
-   private static Logger log = Logger.getLogger(TreeHead.class);
-
-   private Cache<String, Binding> m_cache;
-   
-   private transient HAPartition partition;
-   private transient HAJNDI father;
-
-   // Constructor --------------------------------------------------------
-  
-   public TreeHead(Cache<String, Binding> cache, Fqn<String> root)
-   {
-      super();
-      this.m_cache = cache;
-      this.m_root = root;
-   }
-
-   // Public --------------------------------------------------------
-
-   public void init()
-   {
-      log.debug("HAJNDI registering RPC Handler with HAPartition");
-      this.partition.registerRPCHandler("HAJNDI", this);
-      log.debug("initializing HAJNDITreeCache root");
-      this.putTreeRoot();
-   }
-
-   public void stop()
-   {
-      
-   }
-
-   public void destroy()
-   {
-      log.debug("HAJNDI unregistering RPCHandler with HAPartition");
-      this.partition.unregisterRPCHandler("HAJNDI", this);
-   }
-
-   public void setPartition(HAPartition partition)
-   {
-      this.partition = partition;
-   }
-
-   public void setHARMIHead(HAJNDI father)
-   {
-      this.father = father;
-   }
-
-   // Naming implementation -----------------------------------------
-  
-   public void bind(Name name, Object obj, String className) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("bind, name="+name);
-      }
-      
-      this.internalBind(name, obj, className, false);
-   }
-   
-   public void rebind(Name name, Object obj, String className) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("rebind, name="+name);
-      }
-
-      this.internalBind(name, obj, className, true);
-   }
-
-   public void unbind(Name name) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("unbind, name="+name);
-      }
-      if (name.isEmpty())
-      {
-         // Empty names are not allowed
-         throw new InvalidNameException();
-      }
-      
-      // is the name a context?
-      try
-      {
-         Fqn<String> temp = new Fqn<String>(this.m_root, Fqn.fromString(name.toString()));
-         // TODO why not jst call remove -- why hasChild first?
-         if (this.m_cache.getRoot().hasChild(temp))
-         {
-            this.m_cache.removeNode(temp);
-            return;
-         }
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-      
-      int size = name.size();
-      
-      // get the context and key
-      Fqn<String> ctx;
-      String key = name.get(size - 1);
-      if (size > 1) // find subcontext to which the key is bound
-      {
-         String prefix = name.getPrefix(size - 1).toString();
-         Fqn<String> fqn = Fqn.fromString(prefix);
-         ctx = new Fqn<String>(this.m_root, fqn);
-      }
-      else
-      {
-         ctx = this.m_root;
-      }
-      
-      try
-      {
-         Object removed = this.m_cache.remove(ctx, key);
-         if (removed == null)
-         {
-            if (!this.m_cache.getRoot().hasChild(ctx))
-            {
-                throw new NotContextException(name.getPrefix(size - 1).toString() + " not a context");
-            }
-
-            throw new NameNotFoundException(key + " not bound");
-         }
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   }
-   
-   public Object lookup(Name name) throws NamingException
-   {
-      boolean trace = log.isTraceEnabled();
-      if (trace)
-      {
-         log.trace("lookup, name="+name);
-      }
-   
-      if (name.isEmpty())
-      {
-         // Return this
-         return new NamingContext(null, parser.parse(""), this.getRoot());
-      }
-
-      // is the name a context?
-      try
-      {
-         Node<String, Binding> n = this.m_cache.getRoot().getChild(new Fqn<String>(this.m_root, Fqn.fromString(name.toString())));
-         if (n != null)
-         {
-            Name fullName = (Name) name.clone();
-            return new NamingContext(null, fullName, this.getRoot());
-         }
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   
-      int size = name.size();
-   
-      // get the context and key
-      Fqn<String> ctx;
-      String key = name.get(size - 1);
-      if (size > 1) // find subcontext to which the key is bound
-      {
-         String prefix = name.getPrefix(size - 1).toString();
-         Fqn<String> fqn = Fqn.fromString(prefix);
-         ctx = new Fqn<String>(this.m_root, fqn);
-      }
-      else
-      {
-         ctx = this.m_root;
-      }
-   
-      try
-      {
-         Binding b = this.m_cache.get(ctx, key);
-         
-         // if key not in cache, try local naming server
-         return (b != null) ? b.getObject() : this.internalLookupLocally(name);
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   }
-
-   public Object lookupLocally(Name name) throws NamingException
-   {
-      boolean trace = log.isTraceEnabled();
-      if (trace)
-      {
-         log.trace("lookupLocally, name="+name);
-      }
-
-      // TODO: This is a really big hack here
-      // We cannot do InitialContext().lookup(name) because
-      // we get ClassNotFound errors and ClassLinkage errors.
-      // So, what we do is cheat and get the static localServer variable
-      try
-      {
-         if (NamingContext.localServer != null)
-         {
-            return NamingContext.localServer.lookup(name);
-         }
-
-         return new InitialContext().lookup(name);
-      }
-      catch (NamingException e)
-      {
-         if (trace)
-         {
-            log.trace("lookupLocally failed, name=" + name, e);
-         }
-         throw e;
-      }
-      catch (java.rmi.RemoteException e)
-      {
-         NamingException ne = new NamingException("unknown remote exception");
-         ne.setRootCause(e);
-         if( trace )
-         {
-            log.trace("lookupLocally failed, name=" + name, e);
-         }
-         throw ne;
-      }
-      catch (RuntimeException e)
-      {
-         if (trace)
-         {
-            log.trace("lookupLocally failed, name=" + name, e);
-         }
-         throw e;
-      }
-   }
-   
-   public Collection<NameClassPair> list(Name name) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("list, name="+name);
-      }
-   
-      // get the context
-      Fqn<String> ctx;
-      String ctxName = "";
-      int size = name.size();
-      if (size >= 1)
-      {
-         ctxName = name.toString();
-         Fqn<String> fqn = Fqn.fromString(ctxName);
-         ctx = new Fqn<String>(this.m_root, fqn);
-      }
-      else
-      {
-         ctx = this.m_root;
-      }
-      
-      boolean exists = this.m_cache.getRoot().hasChild(ctx);
-      if (!exists)
-      {
-         try
-         {
-            return Collections.list(new InitialContext().list(name));
-         }
-         catch (NamingException e)
-         {
-            throw new NotContextException(ctxName+ " not a context");
-         }
-      }
-      
-      try
-      {
-         List<NameClassPair> list = new LinkedList<NameClassPair>();
-
-         Node<String, Binding> base = this.m_cache.getRoot().getChild(ctx);
-         if (base != null)
-         {
-            for (Binding b: base.getData().values())
-            {
-               list.add(new NameClassPair(b.getName(),b.getClassName(),true));
-            }
-            
-            // Why doesn't this return Set<String>?
-            Set<Object> children = base.getChildrenNames();
-            if (children != null && !children.isEmpty())
-            {
-               for (Object child: children)
-               {
-                  String node = (String) child;
-                  Name fullName = (Name) name.clone();
-                  fullName.add(node);
-                  list.add(new NameClassPair(node, NamingContext.class.getName(),true));
-               }
-            }
-         }
-         
-         return list;
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   }
-
-   public Collection<Binding> listBindings(Name name) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("listBindings, name="+name);
-      }
-      
-      // get the context
-      Fqn<String> ctx;
-      String ctxName = "";
-      int size = name.size();
-      if (size >= 1)
-      {
-         ctxName = name.toString();
-         Fqn<String> fqn = Fqn.fromString(ctxName);
-         ctx = new Fqn<String>(this.m_root, fqn);
-      }
-      else
-      {
-         ctx = this.m_root;
-      }
-      
-      boolean exists = this.m_cache.getRoot().hasChild(ctx);
-      if (!exists)
-      {
-         // not found in global jndi, look in local.
-         try
-         {
-            return Collections.list(new InitialContext().listBindings(name));
-         }
-         catch (NamingException e)
-         {
-            throw new NotContextException(ctxName+ " not a context");
-         }
-      }
-      
-      try
-      {
-         List<Binding> list = new LinkedList<Binding>();
-         
-         Node<String, Binding> node = this.m_cache.getRoot().getChild(ctx);
-         if (node != null)
-         {
-            Map<String, Binding> data = node.getData();
-            if (data != null && !data.isEmpty())
-            {
-               list.addAll(data.values());
-            }
-            
-            // Why doesn't this return Set<String>?
-            Set<Object> children = node.getChildrenNames();
-            if (children != null && !children.isEmpty())
-            {
-               for (Object obj: children)
-               {
-                  String child = (String) obj;
-                  Name fullName = (Name) name.clone();
-                  fullName.add(child);
-                  NamingContext subCtx = new NamingContext(null, fullName, this.getRoot());
-                  list.add(new Binding(child, NamingContext.class.getName(), subCtx, true));
-               }
-            }
-         }
-         
-         return list;
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   }
-
-   public Context createSubcontext(Name name) throws NamingException
-   {
-      if (log.isTraceEnabled())
-      {
-         log.trace("createSubcontext, name="+name);
-      }
-      
-      int size = name.size();
-      
-      if (size == 0)
-      {
-         throw new InvalidNameException("Cannot pass an empty name to createSubcontext");
-      }
-
-      // does the new context already exist?
-      String str = name.toString();
-      Fqn<String> fqn = Fqn.fromString(str);
-      Fqn<String> ctx = new Fqn<String>(this.m_root, fqn);
-      if (this.m_cache.getRoot().hasChild(ctx))
-      {
-         throw new NameAlreadyBoundException();
-      }
-      
-      // does the prefix context already exist?
-      Fqn<String> pctx;
-      String newctx = name.get(size - 1);
-      if (size > 1) // find subcontext to which the context will be added
-      {
-         String prefix = name.getPrefix(size - 1).toString();
-         Fqn<String> fqn2 = Fqn.fromString(prefix);
-         pctx = new Fqn<String>(this.m_root, fqn2);
-      }
-      else
-      {
-         pctx = this.m_root;
-      }
-      
-      boolean exists = this.m_cache.getRoot().hasChild(pctx);
-      if (!exists)
-      {
-         throw new NotContextException(name.getPrefix(size - 1).toString());
-      }
-
-      Fqn<String> newf = new Fqn<String>(pctx, Fqn.fromString(newctx));
-      try
-      {
-         this.m_cache.put(newf, new HashMap<String, Binding>());
-      }
-      catch (CacheException ce)
-      {
-         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
-         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
-         ne.setStackTrace(ce.getStackTrace());
-         throw ne;
-      }
-   
-      Name fullName = parser.parse("");
-      fullName.addAll(name);
-      
-      return new NamingContext(null, fullName, this.getRoot());
-   }
-
-   public Naming getRoot()
-   {
-      return this.father.getHAStub();
-   }
-   
-   private void putTreeRoot() throws CacheException
-   {
-      if (!this.m_cache.getRoot().hasChild(this.m_root))
-      {
-         this.m_cache.put(this.m_root, null);
-      }
-   }
-  
-   private void internalBind(Name name, Object obj, String className, boolean rebind) throws NamingException
-   {
-      if (name.isEmpty())
-      {  // Empty names are not allowed
-         throw new InvalidNameException();
-      }
-
-      int size = name.size();
-      
-      // get the context and key
-      Fqn<String> ctx;
-      String key = name.get(size - 1);
-      if (size > 1) // find subcontext to which the key will be added
-      {
-         String prefix = name.getPrefix(size - 1).toString();
-         Fqn<String> fqn = Fqn.fromString(prefix);
-         ctx = new Fqn<String>(this.m_root, fqn);
-      }
-      else
-      {
-         ctx = this.m_root;
-      }
-   
-      boolean exists = this.m_cache.getRoot().hasChild(ctx);
-      if (!exists)
-      {
-         throw new NotContextException(name.getPrefix(size - 1).toString() + " not a context");
-         // note - NamingServer throws a CannotProceedException if the client attempts to bind
-         //        to a Reference object having an "nns" address.  This implementation simply
-         //        throws the NotContextException that's used when "nns" isn't present.
-      }
-      if (!rebind)
-      {
-         Node<String, Binding> node = this.m_cache.getRoot().getChild(ctx);
-         if ((node != null) && (node.get(key) != null))
-         {
-            throw new NameAlreadyBoundException(key);
-         }
-      }
-      
-      this.m_cache.put(ctx, key, new Binding(key, className, obj, true));
-   }
-
-   private Object internalLookupLocally(Name name) throws NamingException
-   {
-      boolean trace = log.isTraceEnabled();
-
-      try
-      {
-         // not found in global jndi, look in local.
-         return this.lookupLocally(name);
-      }
-      catch (NameNotFoundException nnfe)
-      {
-         // if we get here, this means we need to try on every node.
-         Object[] args = new Object[1];
-         args[0] = name;
-         List<?> rsp = null;
-         Exception cause = null;
-         try
-         {
-            if (trace)
-            {
-               log.trace("calling lookupLocally(" + name + ") on HAJNDI cluster");
-            }
-            rsp = this.partition.callMethodOnCluster("HAJNDI", "lookupLocally", args, new Class[] { Name.class }, true);
-         }
-         catch (Exception ignored)
-         {
-            if (trace)
-            {
-               log.trace("Clustered lookupLocally("+name+") failed", ignored);
-            }
-            cause = ignored;
-         }
-
-         if (trace)
-         {
-            log.trace("Returned results size: "+ (rsp != null ? rsp.size() : 0));
-         }
-         if (rsp == null || rsp.size() == 0)
-         {
-            NameNotFoundException nnfe2 = new NameNotFoundException(name.toString());
-            nnfe2.setRootCause(cause);
-            throw nnfe2;
-         }
-
-         for (int i = 0; i < rsp.size(); i++)
-         {
-            Object result = rsp.get(i);
-            if (trace)
-            {
-               String type = (result != null ? result.getClass().getName() : "null");
-               log.trace("lookupLocally, i="+i+", value="+result+", type="+type);
-            }
-            // Ignore null and Exception return values
-            if ((result != null) && !(result instanceof Exception))
-            {
-               return result;
-            }
-         }
-         throw nnfe;
-      }
-   }
-}

Added: trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManager.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManager.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManager.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -0,0 +1,569 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.ha.jndi.impl.jbc;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.ha.jndi.spi.DistributedTreeManager;
+import org.jboss.logging.Logger;
+import org.jnp.interfaces.Naming;
+import org.jnp.interfaces.NamingContext;
+import org.jnp.interfaces.NamingParser;
+
+/**
+ *  This class utilizes JBossCache to provide a DistributedTreeManager implementation.
+ *
+ *  @author <a href="mailto:jgauthier at novell.com">Jerry Gauthier</a>
+ *  @author Brian Stansberry
+ *  
+ *  @version $Revision: 74736 $
+ */
+public class JBossCacheDistributedTreeManager
+   implements org.jnp.interfaces.Naming, DistributedTreeManager
+{
+   static final long serialVersionUID = 6342802270002172451L;
+   
+   private static Logger log = Logger.getLogger(JBossCacheDistributedTreeManager.class);
+
+   private static final NamingParser parser = new NamingParser();
+  
+   public static final String DEFAULT_ROOT = "__HA_JNDI__";
+   
+   // Attributes --------------------------------------------------------
+
+   private Cache<String, Binding> m_cache;
+   private Fqn<String> m_root;
+   private Naming haStub;
+   private boolean treeRootSet;
+
+   // Constructor --------------------------------------------------------
+  
+   public JBossCacheDistributedTreeManager()
+   {      
+      super();
+   }
+   
+   // JBossCacheDistributedTreeManagerMBean ----------------------------------
+   
+   public Cache getClusteredCache()
+   {
+      return m_cache;
+   }
+   
+   public void setClusteredCache(Cache cache)
+   {
+      if (treeRootSet)
+      {
+         throw new IllegalStateException("Cannot change clusteredCache after call to init()");
+      }
+      this.m_cache = cache;
+   }
+   
+   public String getRootFqn()
+   {
+      return m_root == null ? DEFAULT_ROOT : m_root.toString();
+   }
+   
+   public void setRootFqn(String rootFqn)
+   {
+      if (treeRootSet)
+      {
+         throw new IllegalStateException("Cannot change rootFqn after call to init()");
+      }
+      
+      m_root = (rootFqn == null) ? null : Fqn.fromString(rootFqn);         
+   }
+   
+   // Public -----------------------------------------------------------------
+
+   public void init()
+   {
+      if (this.haStub == null)
+      {
+         throw new IllegalStateException("Must call setHAStub before starting");
+      }
+      
+      if (this.m_cache == null)
+      {
+         throw new IllegalStateException("Must call setClusteredCache before starting");
+      }
+      
+      log.debug("initializing HAJNDITreeCache root");
+      this.putTreeRoot();
+   }
+
+   public void shutdown()
+   {
+   }
+
+   public Naming getHAStub()
+   {
+      return this.haStub;
+   }
+
+   public void setHAStub(Naming stub)
+   {
+      this.haStub = stub;
+   }
+
+   // Naming implementation -----------------------------------------
+  
+   public void bind(Name name, Object obj, String className) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("bind, name="+name);
+      }
+      
+      this.internalBind(name, obj, className, false);
+   }
+   
+   public void rebind(Name name, Object obj, String className) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("rebind, name="+name);
+      }
+
+      this.internalBind(name, obj, className, true);
+   }
+
+   public void unbind(Name name) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("unbind, name="+name);
+      }
+      if (name.isEmpty())
+      {
+         // Empty names are not allowed
+         throw new InvalidNameException();
+      }
+      
+      // is the name a context?
+      try
+      {
+         Fqn<String> temp = new Fqn<String>(this.m_root, Fqn.fromString(name.toString()));
+         // TODO why not jst call remove -- why hasChild first?
+         if (this.m_cache.getRoot().hasChild(temp))
+         {
+            this.m_cache.removeNode(temp);
+            return;
+         }
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+      
+      int size = name.size();
+      
+      // get the context and key
+      Fqn<String> ctx;
+      String key = name.get(size - 1);
+      if (size > 1) // find subcontext to which the key is bound
+      {
+         String prefix = name.getPrefix(size - 1).toString();
+         Fqn<String> fqn = Fqn.fromString(prefix);
+         ctx = new Fqn<String>(this.m_root, fqn);
+      }
+      else
+      {
+         ctx = this.m_root;
+      }
+      
+      try
+      {
+         Object removed = this.m_cache.remove(ctx, key);
+         if (removed == null)
+         {
+            if (!this.m_cache.getRoot().hasChild(ctx))
+            {
+                throw new NotContextException(name.getPrefix(size - 1).toString() + " not a context");
+            }
+
+            throw new NameNotFoundException(key + " not bound");
+         }
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   }
+   
+   public Object lookup(Name name) throws NamingException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+      {
+         log.trace("lookup, name="+name);
+      }
+   
+      if (name.isEmpty())
+      {
+         // Return this
+         return new NamingContext(null, parser.parse(""), this.getHAStub());
+      }
+
+      // is the name a context?
+      try
+      {
+         Node<String, Binding> n = this.m_cache.getRoot().getChild(new Fqn<String>(this.m_root, Fqn.fromString(name.toString())));
+         if (n != null)
+         {
+            Name fullName = (Name) name.clone();
+            return new NamingContext(null, fullName, this.getHAStub());
+         }
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   
+      int size = name.size();
+   
+      // get the context and key
+      Fqn<String> ctx;
+      String key = name.get(size - 1);
+      if (size > 1) // find subcontext to which the key is bound
+      {
+         String prefix = name.getPrefix(size - 1).toString();
+         Fqn<String> fqn = Fqn.fromString(prefix);
+         ctx = new Fqn<String>(this.m_root, fqn);
+      }
+      else
+      {
+         ctx = this.m_root;
+      }
+   
+      try
+      {
+         Binding b = this.m_cache.get(ctx, key);
+         
+         // if key not in cache, return null
+         return (b != null) ? b.getObject() : null;
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   }
+   
+   public Collection<NameClassPair> list(Name name) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("list, name="+name);
+      }
+   
+      // get the context
+      Fqn<String> ctx;
+      String ctxName = "";
+      int size = name.size();
+      if (size >= 1)
+      {
+         ctxName = name.toString();
+         Fqn<String> fqn = Fqn.fromString(ctxName);
+         ctx = new Fqn<String>(this.m_root, fqn);
+      }
+      else
+      {
+         ctx = this.m_root;
+      }
+      
+      boolean exists = this.m_cache.getRoot().hasChild(ctx);
+      if (!exists)
+      {
+         try
+         {
+            return Collections.list(new InitialContext().list(name));
+         }
+         catch (NamingException e)
+         {
+            throw new NotContextException(ctxName+ " not a context");
+         }
+      }
+      
+      try
+      {
+         List<NameClassPair> list = new LinkedList<NameClassPair>();
+
+         Node<String, Binding> base = this.m_cache.getRoot().getChild(ctx);
+         if (base != null)
+         {
+            for (Binding b: base.getData().values())
+            {
+               list.add(new NameClassPair(b.getName(),b.getClassName(),true));
+            }
+            
+            // Why doesn't this return Set<String>?
+            Set<Object> children = base.getChildrenNames();
+            if (children != null && !children.isEmpty())
+            {
+               for (Object child: children)
+               {
+                  String node = (String) child;
+                  Name fullName = (Name) name.clone();
+                  fullName.add(node);
+                  list.add(new NameClassPair(node, NamingContext.class.getName(),true));
+               }
+            }
+         }
+         
+         return list;
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   }
+
+   public Collection<Binding> listBindings(Name name) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("listBindings, name="+name);
+      }
+      
+      // get the context
+      Fqn<String> ctx;
+      String ctxName = "";
+      int size = name.size();
+      if (size >= 1)
+      {
+         ctxName = name.toString();
+         Fqn<String> fqn = Fqn.fromString(ctxName);
+         ctx = new Fqn<String>(this.m_root, fqn);
+      }
+      else
+      {
+         ctx = this.m_root;
+      }
+      
+      boolean exists = this.m_cache.getRoot().hasChild(ctx);
+      if (!exists)
+      {
+         // not found in global jndi, look in local.
+         try
+         {
+            return Collections.list(new InitialContext().listBindings(name));
+         }
+         catch (NamingException e)
+         {
+            throw new NotContextException(ctxName+ " not a context");
+         }
+      }
+      
+      try
+      {
+         List<Binding> list = new LinkedList<Binding>();
+         
+         Node<String, Binding> node = this.m_cache.getRoot().getChild(ctx);
+         if (node != null)
+         {
+            Map<String, Binding> data = node.getData();
+            if (data != null && !data.isEmpty())
+            {
+               list.addAll(data.values());
+            }
+            
+            // Why doesn't this return Set<String>?
+            Set<Object> children = node.getChildrenNames();
+            if (children != null && !children.isEmpty())
+            {
+               for (Object obj: children)
+               {
+                  String child = (String) obj;
+                  Name fullName = (Name) name.clone();
+                  fullName.add(child);
+                  NamingContext subCtx = new NamingContext(null, fullName, this.getHAStub());
+                  list.add(new Binding(child, NamingContext.class.getName(), subCtx, true));
+               }
+            }
+         }
+         
+         return list;
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   }
+
+   public Context createSubcontext(Name name) throws NamingException
+   {
+      if (log.isTraceEnabled())
+      {
+         log.trace("createSubcontext, name="+name);
+      }
+      
+      int size = name.size();
+      
+      if (size == 0)
+      {
+         throw new InvalidNameException("Cannot pass an empty name to createSubcontext");
+      }
+
+      // does the new context already exist?
+      String str = name.toString();
+      Fqn<String> fqn = Fqn.fromString(str);
+      Fqn<String> ctx = new Fqn<String>(this.m_root, fqn);
+      if (this.m_cache.getRoot().hasChild(ctx))
+      {
+         throw new NameAlreadyBoundException();
+      }
+      
+      // does the prefix context already exist?
+      Fqn<String> pctx;
+      String newctx = name.get(size - 1);
+      if (size > 1) // find subcontext to which the context will be added
+      {
+         String prefix = name.getPrefix(size - 1).toString();
+         Fqn<String> fqn2 = Fqn.fromString(prefix);
+         pctx = new Fqn<String>(this.m_root, fqn2);
+      }
+      else
+      {
+         pctx = this.m_root;
+      }
+      
+      boolean exists = this.m_cache.getRoot().hasChild(pctx);
+      if (!exists)
+      {
+         throw new NotContextException(name.getPrefix(size - 1).toString());
+      }
+
+      Fqn<String> newf = new Fqn<String>(pctx, Fqn.fromString(newctx));
+      try
+      {
+         this.m_cache.put(newf, new HashMap<String, Binding>());
+      }
+      catch (CacheException ce)
+      {
+         // don't chain CacheException since JBoss Cache may not be on remote client's classpath
+         NamingException ne = new NamingException(ce.getClass().getName() + ": " + ce.getMessage());
+         ne.setStackTrace(ce.getStackTrace());
+         throw ne;
+      }
+   
+      Name fullName = parser.parse("");
+      fullName.addAll(name);
+      
+      return new NamingContext(null, fullName, this.getHAStub());
+   }
+   
+   private void putTreeRoot() throws CacheException
+   {
+      if (this.m_root == null)
+      {
+         setRootFqn(DEFAULT_ROOT);
+      }
+      
+      if (!this.m_cache.getRoot().hasChild(this.m_root))
+      {
+         this.m_cache.put(this.m_root, null);
+         this.treeRootSet = true;
+      }
+   }
+  
+   private void internalBind(Name name, Object obj, String className, boolean rebind) throws NamingException
+   {
+      if (name.isEmpty())
+      {  // Empty names are not allowed
+         throw new InvalidNameException();
+      }
+
+      int size = name.size();
+      
+      // get the context and key
+      Fqn<String> ctx;
+      String key = name.get(size - 1);
+      if (size > 1) // find subcontext to which the key will be added
+      {
+         String prefix = name.getPrefix(size - 1).toString();
+         Fqn<String> fqn = Fqn.fromString(prefix);
+         ctx = new Fqn<String>(this.m_root, fqn);
+      }
+      else
+      {
+         ctx = this.m_root;
+      }
+   
+      boolean exists = this.m_cache.getRoot().hasChild(ctx);
+      if (!exists)
+      {
+         throw new NotContextException(name.getPrefix(size - 1).toString() + " not a context");
+         // note - NamingServer throws a CannotProceedException if the client attempts to bind
+         //        to a Reference object having an "nns" address.  This implementation simply
+         //        throws the NotContextException that's used when "nns" isn't present.
+      }
+      if (!rebind)
+      {
+         Node<String, Binding> node = this.m_cache.getRoot().getChild(ctx);
+         if ((node != null) && (node.get(key) != null))
+         {
+            throw new NameAlreadyBoundException(key);
+         }
+      }
+      
+      this.m_cache.put(ctx, key, new Binding(key, className, obj, true));
+   }
+}

Added: trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManagerMBean.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManagerMBean.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/impl/jbc/JBossCacheDistributedTreeManagerMBean.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ha.jndi.impl.jbc;
+
+import org.jboss.cache.Cache;
+
+/**
+ * StandardMBean interface for JBossCacheDistributedTreeManager.
+ * 
+ * @author Brian Stansberry
+ */
+public interface JBossCacheDistributedTreeManagerMBean
+{
+   Cache getClusteredCache();
+   
+   void setClusteredCache(Cache cache);
+   
+   String getRootFqn();
+   
+   void setRootFqn(String rootFqn);
+}

Added: trunk/cluster/src/main/org/jboss/ha/jndi/spi/DistributedTreeManager.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/spi/DistributedTreeManager.java	                        (rev 0)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/spi/DistributedTreeManager.java	2008-08-29 22:16:14 UTC (rev 77666)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ha.jndi.spi;
+
+import java.util.Collection;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NamingException;
+
+import org.jnp.interfaces.Naming;
+
+/**
+ * Manages distributed tree operations for HAJNDI.
+ * 
+ * @author Brian Stansberry
+ */
+public interface DistributedTreeManager
+{
+   /** Initializes the DistributedTreeManager */
+   void init();
+
+   /** Shuts down the DistributedTreeManager */
+   void shutdown();
+
+   /** Bind an object in the distribute tree */
+   void bind(Name name, Object obj, String className) throws NamingException;
+
+   /** Re-bind an object in the distribute tree */
+   void rebind(Name name, Object obj, String className) throws NamingException;
+
+   /** Unbind an object from the distributed tree */
+   void unbind(Name name) throws NamingException;
+
+   /** 
+    * Lookup an object in the distributed tree. Does not throw
+    * NameNotFoundException if nothing is bound under <code>name</code>;
+    * instead it returns <code>null</code>.
+    * 
+    * @param name the name
+    * @return the object bound or <code>null</code>
+    */
+   Object lookup(Name name) throws NamingException;
+   
+   /** List the binding in the distributed tree */
+   Collection<NameClassPair> list(Name name) throws NamingException;
+
+   /** List the bindings in the distributed tree */
+   Collection<Binding> listBindings(Name name) throws NamingException;
+
+   /** Create a subcontext in the distributed tree */
+   Context createSubcontext(Name name) throws NamingException;
+
+   /** Get the Naming object relative to which context's are created */
+   Naming getHAStub();
+
+   /** Set the Naming object relative to which context's are created */
+   void setHAStub(Naming stub);
+}
\ No newline at end of file

Modified: trunk/testsuite/src/resources/cluster/ejb2/passexp/META-INF/partition-passexp-jboss-beans.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/ejb2/passexp/META-INF/partition-passexp-jboss-beans.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/testsuite/src/resources/cluster/ejb2/passexp/META-INF/partition-passexp-jboss-beans.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -173,4 +173,60 @@
       <depends>jboss.remoting:service=NetworkRegistry</depends>
    </bean>
    
+   <bean name="PassExpHAJNDI"
+         class="org.jboss.ha.jndi.HANamingService">    
+
+      <depends>jboss:service=Naming</depends>
+      
+      <!-- The partition used for group RPCs to find locally bound objects on other nodes -->
+      <property name="HAPartition"><inject bean="PassExpPartition"/></property>
+      
+      <!-- Handler for the replicated tree -->
+      <property name="distributedTreeManager">
+         <bean class="org.jboss.ha.jndi.impl.jbc.JBossCacheDistributedTreeManager">
+            <property name="clusteredCache"><inject bean="PassExpPartition" property="clusteredCache"/></property>
+         </bean>
+      </property>
+      
+      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
+      <property name="lookupPool"><inject bean="PassExpThreadPool"/></property>
+      
+      <!-- Bind address of bootstrap endpoint -->
+      <property name="bindAddress">${jboss.bind.address}</property>
+      <!-- Port on which the HA-JNDI stub is made available -->
+      <property name="port">11100</property>
+      
+      <!-- Bind address of the HA-JNDI RMI endpoint -->
+      <property name="rmiBindAddress">${jboss.bind.address}</property>
+      
+      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
+      <property name="rmiPort">11101</property>
+      
+      <!-- Accept backlog of the bootstrap socket -->
+      <property name="backlog">50</property>
+
+      <!-- A flag to disable the auto discovery via multicast -->
+      <property name="discoveryDisabled">false</property>
+      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
+      specified and a BindAddress is specified, the BindAddress will be used. -->
+      <property name="autoDiscoveryBindAddress">${jboss.bind.address}</property>
+      <!-- Multicast Address and group port used for auto-discovery -->
+      <property name="autoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</property>
+      <property name="autoDiscoveryGroup">11102</property>
+      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
+      <property name="autoDiscoveryTTL">16</property>
+      
+      <!-- The load balancing policy for HA-JNDI -->
+      <property name="loadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</property>
+
+      <!-- Client socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="clientSocketFactory">custom</property>
+      -->
+      <!-- Server socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="serverSocketFactory">custom</property>
+      -->
+   </bean>
+   
 </deployment>

Modified: trunk/testsuite/src/resources/cluster/ejb2/passexp/partition-passexp-service.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/ejb2/passexp/partition-passexp-service.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/testsuite/src/resources/cluster/ejb2/passexp/partition-passexp-service.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -8,50 +8,6 @@
 
 <server>
    
-   <mbean code="org.jboss.ha.jndi.HANamingService"
-      name="jboss:service=HAJNDI,partitionName=PassExpPartition">      
-      
-      <!-- The partition used for group RPCs to find locally bound objects -->
-      <attribute name="HAPartition"><inject bean="PassExpPartition"/></attribute>
-      <!-- The cache for storing the replicated tree  -->
-      <attribute name="ClusteredCache"><inject bean="PassExpPartition" property="clusteredCache"/></attribute>
-      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
-      <attribute name="LookupPool"><inject bean="PassExpThreadPool"/></attribute>
-      
-      <!-- Bind address of bootstrap endpoint -->
-      <attribute name="BindAddress">${jboss.bind.address}</attribute>
-      <!-- Port on which the HA-JNDI stub is made available -->
-      <attribute name="Port">11100</attribute>
-      <!-- Bind address of the HA-JNDI RMI endpoint -->
-      <attribute name="RmiBindAddress">${jboss.bind.address}</attribute>
-      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
-      <attribute name="RmiPort">11101</attribute>
-      <!-- Accept backlog of the bootstrap socket -->
-      <attribute name="Backlog">50</attribute>
-
-      <!-- A flag to disable the auto discovery via multicast -->
-      <attribute name="DiscoveryDisabled">false</attribute>
-      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
-      specified and a BindAddress is specified, the BindAddress will be used. -->
-      <attribute name="AutoDiscoveryBindAddress">${jboss.bind.address}</attribute>
-      <!-- Multicast Address and group port used for auto-discovery -->
-      <attribute name="AutoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</attribute>
-      <attribute name="AutoDiscoveryGroup">11102</attribute>
-      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
-      <attribute name="AutoDiscoveryTTL">16</attribute>
-      <!-- The load balancing policy for HA-JNDI -->
-      <attribute name="LoadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</attribute>
-
-      <!-- Client socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ClientSocketFactory">custom</attribute>
-      -->
-      <!-- Server socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ServerSocketFactory">custom</attribute>
-      -->
-   </mbean>
-
    <!-- ==================================================================== -->
    <!-- HA Detached Invoker using JBoss Remoting for transport               -->
    <!-- ==================================================================== -->

Modified: trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -162,4 +162,60 @@
       <depends>jboss.remoting:service=NetworkRegistry</depends>
    </bean>
    
+   <bean name="RestartPartitionHAJNDI"
+         class="org.jboss.ha.jndi.HANamingService">    
+
+      <depends>jboss:service=Naming</depends>
+      
+      <!-- The partition used for group RPCs to find locally bound objects on other nodes -->
+      <property name="HAPartition"><inject bean="RestartPartition"/></property>
+      
+      <!-- Handler for the replicated tree -->
+      <property name="distributedTreeManager">
+         <bean class="org.jboss.ha.jndi.impl.jbc.JBossCacheDistributedTreeManager">
+            <property name="clusteredCache"><inject bean="RestartPartition" property="clusteredCache"/></property>
+         </bean>
+      </property>
+      
+      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
+      <property name="lookupPool"><inject bean="RestartPartitionThreadPool"/></property>
+      
+      <!-- Bind address of bootstrap endpoint -->
+      <property name="bindAddress">${jboss.bind.address}</property>
+      <!-- Port on which the HA-JNDI stub is made available -->
+      <property name="port">11100</property>
+      
+      <!-- Bind address of the HA-JNDI RMI endpoint -->
+      <property name="rmiBindAddress">${jboss.bind.address}</property>
+      
+      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
+      <property name="rmiPort">11101</property>
+      
+      <!-- Accept backlog of the bootstrap socket -->
+      <property name="backlog">50</property>
+
+      <!-- A flag to disable the auto discovery via multicast -->
+      <property name="discoveryDisabled">false</property>
+      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
+      specified and a BindAddress is specified, the BindAddress will be used. -->
+      <property name="autoDiscoveryBindAddress">${jboss.bind.address}</property>
+      <!-- Multicast Address and group port used for auto-discovery -->
+      <property name="autoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</property>
+      <property name="autoDiscoveryGroup">11102</property>
+      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
+      <property name="autoDiscoveryTTL">16</property>
+      
+      <!-- The load balancing policy for HA-JNDI -->
+      <property name="loadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</property>
+
+      <!-- Client socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="clientSocketFactory">custom</property>
+      -->
+      <!-- Server socket factory to be used for client-server
+           RMI invocations during JNDI queries
+      <property name="serverSocketFactory">custom</property>
+      -->
+   </bean>
+   
 </deployment>

Modified: trunk/testsuite/src/resources/cluster/partition/partition-restart-service.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/partition/partition-restart-service.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/testsuite/src/resources/cluster/partition/partition-restart-service.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -8,50 +8,6 @@
 
 <server>
    
-   <mbean code="org.jboss.ha.jndi.HANamingService"
-      name="jboss:service=HAJNDI,partitionName=RestartPartition">      
-      
-      <!-- The partition used for group RPCs to find locally bound objects -->
-      <attribute name="HAPartition"><inject bean="RestartPartition"/></attribute>
-      <!-- The cache for storing the replicated tree  -->
-      <attribute name="ClusteredCache"><inject bean="RestartPartition" property="clusteredCache"/></attribute>
-      <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
-      <attribute name="LookupPool"><inject bean="RestartPartitionThreadPool"/></attribute>
-      
-      <!-- Bind address of bootstrap endpoint -->
-      <attribute name="BindAddress">${jboss.bind.address}</attribute>
-      <!-- Port on which the HA-JNDI stub is made available -->
-      <attribute name="Port">11100</attribute>
-      <!-- Bind address of the HA-JNDI RMI endpoint -->
-      <attribute name="RmiBindAddress">${jboss.bind.address}</attribute>
-      <!-- RmiPort to be used by the HA-JNDI service once bound. 0 => auto. -->
-      <attribute name="RmiPort">11101</attribute>
-      <!-- Accept backlog of the bootstrap socket -->
-      <attribute name="Backlog">50</attribute>
-
-      <!-- A flag to disable the auto discovery via multicast -->
-      <attribute name="DiscoveryDisabled">false</attribute>
-      <!-- Set the auto-discovery bootstrap multicast bind address. If not 
-      specified and a BindAddress is specified, the BindAddress will be used. -->
-      <attribute name="AutoDiscoveryBindAddress">${jboss.bind.address}</attribute>
-      <!-- Multicast Address and group port used for auto-discovery -->
-      <attribute name="AutoDiscoveryAddress">${jboss.partition.udpGroup:230.0.0.4}</attribute>
-      <attribute name="AutoDiscoveryGroup">11102</attribute>
-      <!-- The TTL (time-to-live) for autodiscovery IP multicast packets -->
-      <attribute name="AutoDiscoveryTTL">16</attribute>
-      <!-- The load balancing policy for HA-JNDI -->
-      <attribute name="LoadBalancePolicy">org.jboss.ha.framework.interfaces.RoundRobin</attribute>
-
-      <!-- Client socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ClientSocketFactory">custom</attribute>
-      -->
-      <!-- Server socket factory to be used for client-server
-           RMI invocations during JNDI queries
-      <attribute name="ServerSocketFactory">custom</attribute>
-      -->
-   </mbean>
-
    <!-- ==================================================================== -->
    <!-- HA Detached Invoker using JBoss Remoting for transport               -->
    <!-- ==================================================================== -->

Modified: trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml
===================================================================
--- trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml	2008-08-29 21:58:21 UTC (rev 77665)
+++ trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml	2008-08-29 22:16:14 UTC (rev 77666)
@@ -50,8 +50,14 @@
    	<depends>HAPartition</depends>
       	       
       <property name="HAPartition"><inject bean="HAPartition"/></property>
-      <property name="clusteredCache"><inject bean="HAPartition" property="clusteredCache"/></property>
       
+      <!-- Handler for the replicated tree -->
+      <property name="distributedTreeManager">
+         <bean class="org.jboss.ha.jndi.impl.jbc.JBossCacheDistributedTreeManager">
+            <property name="clusteredCache"><inject bean="HAPartition" property="clusteredCache"/></property>
+         </bean>
+      </property>
+      
       <!-- Bind address of bootstrap endpoint -->
       <property name="bindAddress">${jboss.bind.address}</property>
       <!-- Port on which the HA-JNDI stub is made available -->




More information about the jboss-cvs-commits mailing list