[jboss-cvs] JBossAS SVN: r79874 - in trunk: cluster/src/main/org/jboss/ha/jndi and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Oct 21 17:41:40 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-10-21 17:41:39 -0400 (Tue, 21 Oct 2008)
New Revision: 79874

Modified:
   trunk/cluster/src/etc/hajndi-jboss-beans.xml
   trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.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/partition/partition-restart-jboss-beans.xml
   trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml
Log:
[JBAS-6023] [JBAS-6080]  Reapply r79679, r79864 commits

Modified: trunk/cluster/src/etc/hajndi-jboss-beans.xml
===================================================================
--- trunk/cluster/src/etc/hajndi-jboss-beans.xml	2008-10-21 21:37:56 UTC (rev 79873)
+++ trunk/cluster/src/etc/hajndi-jboss-beans.xml	2008-10-21 21:41:39 UTC (rev 79874)
@@ -11,8 +11,6 @@
    <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>
            
       
@@ -26,6 +24,8 @@
          </bean>
       </property>
       
+      <property name="localNamingInstance"><inject bean="jboss:service=NamingBeanImpl" property="namingInstance"/></property>
+      
       <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
       <property name="lookupPool"><inject bean="jboss.system:service=ThreadPool"/></property>
       

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-10-21 21:37:56 UTC (rev 79873)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-10-21 21:41:39 UTC (rev 79874)
@@ -28,34 +28,35 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.net.DatagramPacket;
+import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.MulticastSocket;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketAddress;
 import java.net.UnknownHostException;
 import java.rmi.MarshalledObject;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 
-import javax.management.ObjectInstance;
 import javax.management.ObjectName;
-import javax.management.Query;
-import javax.management.QueryExp;
 import javax.net.ServerSocketFactory;
 
+import org.apache.commons.logging.Log;
 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;
-import org.jboss.mx.util.MBeanProxyExt;
 import org.jboss.system.ServiceMBeanSupport;
 import org.jboss.util.threadpool.BasicThreadPool;
 import org.jboss.util.threadpool.BasicThreadPoolMBean;
 import org.jboss.util.threadpool.ThreadPool;
+import org.jgroups.util.Util;
 import org.jnp.interfaces.Naming;
 import org.jnp.interfaces.NamingContext;
 
@@ -105,6 +106,11 @@
     * The proxy factory service that generates the Naming stub
     */
    private ObjectName proxyFactory;
+   
+   /**
+    * The local (non-HA) Naming instance. 
+    */
+   private Naming localNamingInstance;
 
    /**
     * The interface to bind to. This is useful for multi-homed hosts that want
@@ -195,6 +201,16 @@
       this.distributedTreeManager = distributedTreeManager;
    }
 
+   public Naming getLocalNamingInstance()
+   {
+      return localNamingInstance;
+   }
+
+   public void setLocalNamingInstance(Naming localNamingInstance)
+   {
+      this.localNamingInstance = localNamingInstance;
+   }
+
    public ObjectName getProxyFactoryObjectName()
    {
       return this.proxyFactory;
@@ -329,7 +345,7 @@
       this.log.debug("Initializing HAJNDI server on partition: " + this.clusterPartition.getPartitionName());
       
       // Start HAJNDI service
-      this.theServer = new HAJNDI(this.clusterPartition, this.distributedTreeManager);
+      this.theServer = new HAJNDI(this.clusterPartition, this.distributedTreeManager, localNamingInstance);
 
       // Build the Naming interface method map
       Map<Long, Method> map = new HashMap<Long, Method>(13);
@@ -482,44 +498,7 @@
    }
 
    // Protected -----------------------------------------------------
-   
-   protected HAPartition findHAPartitionWithName(String name)
-   {
-      HAPartition result = null;
-      // Class name match does not work with the AOP proxy :(
-//    QueryExp classEQ = Query.eq(Query.classattr(),
-//             Query.value(ClusterPartition.class.getName()));
-      QueryExp matchName = Query.match(Query.attr("Name"),
-         Query.value("ClusterPartition"));
-      QueryExp matchPartitionName = Query.match(Query.attr("PartitionName"),
-         Query.value(name));
-      QueryExp exp = Query.and(matchName, matchPartitionName);
-      Set<?> mbeans = this.getServer().queryMBeans(null, exp);
-      if (mbeans != null && mbeans.size() > 0)
-      {
-         for (Object mbean: mbeans)
-         {
-            ObjectInstance inst = (ObjectInstance) mbean;
-            try
-            {
-               ClusterPartitionMBean cp =
-                  (ClusterPartitionMBean) MBeanProxyExt.create(
-                   ClusterPartitionMBean.class,
-                   inst.getObjectName(),
-                   this.getServer());
-               result = cp.getHAPartition();
-               break;
-            }
-            catch (Exception e)
-            {
-               // Ignore
-            }
-         }
-      }
 
-      return result;
-   }
-
    /**
     * Get the Naming proxy for the transport. This version looks  up the
     * proxyFactory service Proxy attribute. Subclasses can override this to set
@@ -555,21 +534,40 @@
       public void start() throws Exception
       {
          this.stopping = false;
+         
+         // Set up the multicast socket on which we listen for discovery requests
+         
+         this.group = InetAddress.getByName(DetachedHANamingService.this.adGroupAddress);
+         
+         // On Linux, we avoid cross-talk problem by binding the MulticastSocket
+         // to the multicast address. See https://jira.jboss.org/jira/browse/JGRP-777
+         if(checkForPresence("os.name", "linux"))
+         {             
+            this.socket = createMulticastSocket(group, DetachedHANamingService.this.adGroupPort);
+         }
+         else
+         {
+            this.socket = new MulticastSocket(DetachedHANamingService.this.adGroupPort);
+         }
+         
+         // If there is a valid bind address, set the socket interface to it         
          // Use the jndi bind address if there is no discovery address
          if (DetachedHANamingService.this.discoveryBindAddress == null)
          {
             DetachedHANamingService.this.discoveryBindAddress = DetachedHANamingService.this.bindAddress;
          }
-         this.socket = new MulticastSocket(DetachedHANamingService.this.adGroupPort);
-         // If there is a bind address valid, set the socket interface to it
-         if (DetachedHANamingService.this.discoveryBindAddress != null && DetachedHANamingService.this.discoveryBindAddress.isAnyLocalAddress() == false)
+         
+         if (DetachedHANamingService.this.discoveryBindAddress != null 
+               && DetachedHANamingService.this.discoveryBindAddress.isAnyLocalAddress() == false)
          {
             this.socket.setInterface(DetachedHANamingService.this.discoveryBindAddress);
          }
+         
          this.socket.setTimeToLive(DetachedHANamingService.this.autoDiscoveryTTL);
-         this.group = InetAddress.getByName(DetachedHANamingService.this.adGroupAddress);
          this.socket.joinGroup(this.group);
 
+         
+         // Determine the hostname:port string we will return to discovery requests
          String address = DetachedHANamingService.this.getBindAddress();
          /* An INADDR_ANY (0.0.0.0 || null) address is useless as the value
             sent to a remote client so check for this and use the local host
@@ -667,6 +665,65 @@
          this.receiverStopped = true;
          this.log.debug("Discovery request thread end");
       }
+
+      private boolean checkForPresence(final String key, String value)
+      {
+         try
+         {
+            String tmp = null;
+            if (System.getSecurityManager() == null)
+            {
+               tmp = System.getProperty(key);
+            }
+            else
+            {
+               tmp = (String) AccessController.doPrivileged(new PrivilegedAction()
+                  {
+                     public Object run()
+                     {
+                        return System.getProperty(key);
+                     }
+   
+                  });
+            }
+
+            return tmp != null && tmp.trim().toLowerCase().startsWith(value);
+         }
+         catch (Throwable t)
+         {
+            return false;
+         }
+      }
+      
+      private MulticastSocket createMulticastSocket(InetAddress mcast_addr, int port) throws IOException 
+      {
+        if(mcast_addr != null && !mcast_addr.isMulticastAddress()) {
+            log.warn("mcast_addr (" + mcast_addr + ") is not a multicast address, will be ignored");
+            return new MulticastSocket(port);
+        }
+
+        SocketAddress saddr=new InetSocketAddress(mcast_addr, port);
+        MulticastSocket retval=null;
+
+        try {
+            retval=new MulticastSocket(saddr);
+        }
+        catch(IOException ex) {
+            StringBuilder sb=new StringBuilder();
+             String type=mcast_addr != null ? mcast_addr instanceof Inet4Address? "IPv4" : "IPv6" : "n/a";
+             sb.append("could not bind to " + mcast_addr + " (" + type + " address)");
+             sb.append("; make sure your mcast_addr is of the same type as the IP stack (IPv4 or IPv6).");
+             sb.append("\nWill ignore mcast_addr, but this may lead to cross talking " +
+                     "(see http://www.jboss.com/wiki/Edit.jsp?page=CrossTalking for details). ");
+             sb.append("\nException was: " + ex);
+             log.warn(sb);
+        }
+        if(retval == null)
+        {
+            retval=new MulticastSocket(port);
+        }
+        return retval;
+    }
    }
 
    /**

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java	2008-10-21 21:37:56 UTC (rev 79873)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/HAJNDI.java	2008-10-21 21:41:39 UTC (rev 79874)
@@ -34,13 +34,13 @@
 import org.jboss.ha.framework.interfaces.HAPartition;
 import org.jboss.ha.jndi.spi.DistributedTreeManager;
 import org.jboss.logging.Logger;
-import org.jnp.interfaces.NamingContext;
+import org.jnp.interfaces.Naming;
 
 /**
  *  Provides the Naming implemenation. Lookups will look for Names in 
- *  the injected DistributedTreeManager and if not found will delegate to the local 
+ *  the injected DistributedTreeManager and if not found will distributedTreeManager 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 
+ *  using the provided partition.  All other Naming operations distributedTreeManager to the 
  *  DistributedTreeManager.
  *
  *  @author <a href="mailto:bill at burkecentral.com">Bill Burke</a>
@@ -60,24 +60,32 @@
    // Attributes --------------------------------------------------------
    
    private final HAPartition partition;
-   private final DistributedTreeManager delegate;
+   private final DistributedTreeManager distributedTreeManager;
+   private final Naming localNamingInstance;
+   private boolean missingLocalNamingLogged;
 
    // Constructor --------------------------------------------------------
   
-   public HAJNDI(HAPartition partition, DistributedTreeManager delegate)
+   public HAJNDI(HAPartition partition, DistributedTreeManager distributedTreeManager, Naming localNamingInstance)
    {
       if (partition == null)
       {
          throw new IllegalArgumentException("Null partition");
       }
       
-      if (delegate == null)
+      if (distributedTreeManager == null)
       {
-         throw new IllegalArgumentException("Null delegate");
+         throw new IllegalArgumentException("Null distributedTreeManager");
       }
       
+      if (localNamingInstance == null)
+      {
+         log.debug("No localNamingInstance provided; injecting a local naming instance is recommended");
+      }
+      
       this.partition = partition;
-      this.delegate = delegate;
+      this.distributedTreeManager = distributedTreeManager;
+      this.localNamingInstance = localNamingInstance;
    }
    
    // Public --------------------------------------------------------
@@ -86,14 +94,14 @@
    {
       log.debug("HAJNDI registering RPC Handler with HAPartition");
       this.partition.registerRPCHandler("HAJNDI", this);
-      this.delegate.init();
+      this.distributedTreeManager.init();
    }
 
    public void shutdown()
    {
       log.debug("HAJNDI unregistering RPCHandler with HAPartition");
       this.partition.unregisterRPCHandler("HAJNDI", this);
-      this.delegate.shutdown();
+      this.distributedTreeManager.shutdown();
    }
 
    /**
@@ -112,20 +120,19 @@
          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
+      // So, what we prefer to use an injected local Naming instance
       try
       {
-         if (NamingContext.getLocal() != null)
+         if (localNamingInstance != null)
          {
-            return NamingContext.getLocal().lookup(name);
+            return localNamingInstance.lookup(name);
          }
 
          return new InitialContext().lookup(name);
       }
-      catch (NamingException e)
+      catch (NameNotFoundException e)
       {
          if (trace)
          {
@@ -133,6 +140,14 @@
          }
          throw e;
       }
+      catch (NamingException e)
+      {
+         if (!logMissingLocalNamingInstance(e) && trace)
+         {
+            log.trace("lookupLocally failed, name=" + name, e);
+         }
+         throw e;
+      }
       catch (java.rmi.RemoteException e)
       {
          NamingException ne = new NamingException("unknown remote exception");
@@ -145,12 +160,17 @@
       }
       catch (RuntimeException e)
       {
-         if (trace)
+         if (!logMissingLocalNamingInstance(e) && trace)
          {
             log.trace("lookupLocally failed, name=" + name, e);
          }
          throw e;
       }
+      catch (Error e)
+      {
+         logMissingLocalNamingInstance(e);
+         throw e;
+      }
    }
 
    // Naming implementation -----------------------------------------
@@ -158,22 +178,22 @@
 
    public synchronized void bind(Name name, Object obj, String className) throws NamingException
    {
-      this.delegate.bind(name, obj, className);
+      this.distributedTreeManager.bind(name, obj, className);
    }
 
    public synchronized void rebind(Name name, Object obj, String className) throws NamingException
    {
-      this.delegate.rebind(name, obj, className);
+      this.distributedTreeManager.rebind(name, obj, className);
    }
 
    public synchronized void unbind(Name name) throws NamingException
    {
-      this.delegate.unbind(name);
+      this.distributedTreeManager.unbind(name);
    }
 
    public Object lookup(Name name) throws NamingException
    {
-      Object binding = this.delegate.lookup(name);
+      Object binding = this.distributedTreeManager.lookup(name);
       if (binding == null)
       {
          try
@@ -194,17 +214,17 @@
 
    public Collection<NameClassPair> list(Name name) throws NamingException
    {
-      return this.delegate.list(name) ;
+      return this.distributedTreeManager.list(name) ;
    }
     
    public Collection<Binding> listBindings(Name name) throws NamingException
    {
-      return this.delegate.listBindings(name);
+      return this.distributedTreeManager.listBindings(name);
    }
    
    public javax.naming.Context createSubcontext(Name name) throws NamingException
    {
-      return this.delegate.createSubcontext(name);
+      return this.distributedTreeManager.createSubcontext(name);
    }
    
    // ----------------------------------------------------------------  Private
@@ -263,4 +283,24 @@
       
       return null;
    }
+   
+   /**
+    * One time and one time only logs a WARN if localNamingInstance was
+    * not passed to our constructor and an error condition occurred while
+    * attempting to do a local lookup via new InitialContext().
+    * 
+    * @param t the error that occurred
+    * @return <code>true</code> if this method logged a WARN
+    */
+   private boolean logMissingLocalNamingInstance(Throwable t)
+   {
+      if (localNamingInstance == null && !missingLocalNamingLogged)
+      {
+         log.warn("No localNamingInstance configured and lookup via new InitialContext() failed; " +
+               "injecting a local naming instance is recommended", t);
+         missingLocalNamingLogged = true;
+         return true;
+      }
+      return false;
+   }
 }

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-10-21 21:37:56 UTC (rev 79873)
+++ trunk/testsuite/src/resources/cluster/ejb2/passexp/META-INF/partition-passexp-jboss-beans.xml	2008-10-21 21:41:39 UTC (rev 79874)
@@ -178,8 +178,6 @@
    <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>
       
@@ -190,6 +188,8 @@
          </bean>
       </property>
       
+      <property name="localNamingInstance"><inject bean="jboss:service=NamingBeanImpl" property="namingInstance"/></property>
+      
       <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
       <property name="lookupPool"><inject bean="PassExpThreadPool"/></property>
       

Modified: trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml	2008-10-21 21:37:56 UTC (rev 79873)
+++ trunk/testsuite/src/resources/cluster/partition/partition-restart-jboss-beans.xml	2008-10-21 21:41:39 UTC (rev 79874)
@@ -167,8 +167,6 @@
    <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>
       
@@ -179,6 +177,8 @@
          </bean>
       </property>
       
+      <property name="localNamingInstance"><inject bean="jboss:service=NamingBeanImpl" property="namingInstance"/></property>
+      
       <!-- The thread pool used to control the bootstrap and auto discovery lookups -->
       <property name="lookupPool"><inject bean="RestartPartitionThreadPool"/></property>
       

Modified: trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml
===================================================================
--- trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml	2008-10-21 21:37:56 UTC (rev 79873)
+++ trunk/testsuite/src/resources/naming/restart/naming-restart-jboss-beans.xml	2008-10-21 21:41:39 UTC (rev 79874)
@@ -58,6 +58,8 @@
          </bean>
       </property>
       
+      <property name="localNamingInstance"><inject bean="RestartNamingBean" property="namingInstance"/></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