[jboss-cvs] JBossAS SVN: r92169 - in projects/ejb3/trunk/proxy-impl/src: test/java/org/jboss/ejb3/test/proxy/impl and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Aug 9 08:11:54 EDT 2009


Author: jaikiran
Date: 2009-08-09 08:11:54 -0400 (Sun, 09 Aug 2009)
New Revision: 92169

Added:
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/Calculator.java
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/CalculatorImpl.java
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/IllegalInvocationException.java
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/NotToBeInvokedInterceptor.java
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/unit/
   projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/unit/IsLocalProxyFactoryInterceptorTestCase.java
Modified:
   projects/ejb3/trunk/proxy-impl/src/main/java/org/jboss/ejb3/proxy/impl/remoting/IsLocalProxyFactoryInterceptor.java
Log:
EJBTHREE-1868 Fixed the IsLocalProxyFactoryInterceptor which was considering local calls as remote (resulting in the call going through the network stack)

Modified: projects/ejb3/trunk/proxy-impl/src/main/java/org/jboss/ejb3/proxy/impl/remoting/IsLocalProxyFactoryInterceptor.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/main/java/org/jboss/ejb3/proxy/impl/remoting/IsLocalProxyFactoryInterceptor.java	2009-08-09 11:19:07 UTC (rev 92168)
+++ projects/ejb3/trunk/proxy-impl/src/main/java/org/jboss/ejb3/proxy/impl/remoting/IsLocalProxyFactoryInterceptor.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -31,24 +31,51 @@
 
 /**
  * Routes the call to the local container, bypassing further client-side
- * interceptors and any remoting layer, if this interceptor was created 
+ * interceptors and any remoting layer, if this interceptor was created
  * in this JVM.
  *
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
  * @author Brian Stansberry
- * 
+ *
  * @version $Revision: 61667 $
  */
 public class IsLocalProxyFactoryInterceptor implements Interceptor, Serializable
 {
    private static final long serialVersionUID = -1264055696758370812L;
 
+   // Important implementation note : The order of the class field initialization
+   // (i.e. static fields) is important. This "stamp" field needs to be initialized
+   // *before* the static "singleton" field.
+   //
+   // If singleton is declared before "stamp" then it will cause the following bug
+   //
+   // public static final IsLocalProxyFactoryInterceptor singleton = new IsLocalProxyFactoryInterceptor();
+   // private static final long stamp = System.currentTimeMillis();
+   // private long marshalledStamp = stamp;
+   //
+   // 1) Default class initialization occurs and all static fields including "stamp" are set to default values
+   // 2) So at this point stamp = 0
+   // 3) Then class field intializer blocks are executed. Since "singleton" field intialization comes
+   //   before "stamp" field initialization, the new IsLocalProxyFactotyInterceptor gets called.
+   //   This results in object field initialization where the "marshalledStamp" is first set to
+   //   default value of 0 and then the object field initializer is called. The object field initializer
+   //   then sets the "marshalledStamp" to the value of "stamp" which is 0 (as per #2) because the static field
+   //   initializer for "stamp" has not yet executed.
+   // 4) So ultimately "marshalledStamp" will hold 0.
+   // 5) After the class field intializer block for "singleton" field completes, it moves onto class field
+   //   initialization of "stamp" and sets the value of "stamp" to the current system time (=xxxxx)
+   // 6) So ultimately after this complete initialization process, the values of marshalledStamp = 0
+   //   and that of stamp = xxxx
+   // 7) At a later point of time when isLocal() compares these 2 values(through stamp == marshalledStamp) it always returns
+   //   false and hence all calls are considered remote.
+   //
+   // So the rule is - declare class field "stamp" before the class field "singleton"
+   private static final long stamp = System.currentTimeMillis();
+
    public static final IsLocalProxyFactoryInterceptor singleton = new IsLocalProxyFactoryInterceptor();
 
    private static final Logger log = Logger.getLogger(IsLocalProxyFactoryInterceptor.class);
 
-   private static final long stamp = System.currentTimeMillis();
-
    private long marshalledStamp = stamp;
 
    public String getName()
@@ -69,6 +96,7 @@
             return response.getResponse();
          }
       }
+      log.debug("NOT a local invocation, passing the control to next interceptor");
       return invocation.invokeNext();
    }
 

Added: projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/Calculator.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/Calculator.java	                        (rev 0)
+++ projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/Calculator.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -0,0 +1,33 @@
+/*
+* 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.ejb3.test.proxy.impl.ejbthree1868;
+
+/**
+ * NoOp
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public interface Calculator
+{
+   int add(int a, int b);
+}

Added: projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/CalculatorImpl.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/CalculatorImpl.java	                        (rev 0)
+++ projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/CalculatorImpl.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -0,0 +1,38 @@
+/*
+* 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.ejb3.test.proxy.impl.ejbthree1868;
+
+/**
+ * CalculatorImpl
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class CalculatorImpl implements Calculator
+{
+
+   public int add(int a, int b)
+   {
+      return a + b;
+   }
+
+}

Added: projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/IllegalInvocationException.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/IllegalInvocationException.java	                        (rev 0)
+++ projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/IllegalInvocationException.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -0,0 +1,42 @@
+/*
+* 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.ejb3.test.proxy.impl.ejbthree1868;
+
+/**
+ * IllegalInvocationException
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class IllegalInvocationException extends RuntimeException
+{
+
+   public IllegalInvocationException()
+   {
+
+   }
+
+   public IllegalInvocationException(String msg)
+   {
+      super(msg);
+   }
+}

Added: projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/NotToBeInvokedInterceptor.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/NotToBeInvokedInterceptor.java	                        (rev 0)
+++ projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/NotToBeInvokedInterceptor.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -0,0 +1,46 @@
+/*
+* 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.ejb3.test.proxy.impl.ejbthree1868;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+
+/**
+ * NotToBeInvokedInterceptor
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class NotToBeInvokedInterceptor implements Interceptor
+{
+
+   public String getName()
+   {
+      return this.getClass().getName();
+   }
+
+   public Object invoke(Invocation invocation) throws Throwable
+   {
+      throw new IllegalInvocationException();
+   }
+
+}

Added: projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/unit/IsLocalProxyFactoryInterceptorTestCase.java
===================================================================
--- projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/unit/IsLocalProxyFactoryInterceptorTestCase.java	                        (rev 0)
+++ projects/ejb3/trunk/proxy-impl/src/test/java/org/jboss/ejb3/test/proxy/impl/ejbthree1868/unit/IsLocalProxyFactoryInterceptorTestCase.java	2009-08-09 12:11:54 UTC (rev 92169)
@@ -0,0 +1,109 @@
+/*
+* 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.ejb3.test.proxy.impl.ejbthree1868.unit;
+
+import java.lang.reflect.Proxy;
+
+import org.jboss.aop.Dispatcher;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aspects.remoting.PojiProxy;
+import org.jboss.ejb3.proxy.impl.remoting.IsLocalProxyFactoryInterceptor;
+import org.jboss.ejb3.test.proxy.impl.ejbthree1868.Calculator;
+import org.jboss.ejb3.test.proxy.impl.ejbthree1868.CalculatorImpl;
+import org.jboss.ejb3.test.proxy.impl.ejbthree1868.IllegalInvocationException;
+import org.jboss.ejb3.test.proxy.impl.ejbthree1868.NotToBeInvokedInterceptor;
+import org.jboss.logging.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * IsLocalProxyFactoryInterceptorTestCase
+ *
+ * Testcase for EJBTHREE-1868 which tests that the {@link IsLocalProxyFactoryInterceptor}
+ * correctly detects local invocations. The bug that was identified in EJBTHREE-1868
+ * showed that the {@link IsLocalProxyFactoryInterceptor} always considered the local
+ * calls are remote (resulting in the call going through network stack). The bug was a
+ * result of incorrect ordering of static fields in the {@link IsLocalProxyFactoryInterceptor}
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class IsLocalProxyFactoryInterceptorTestCase
+{
+
+   /**
+    * Logger
+    */
+   private static Logger logger = Logger.getLogger(IsLocalProxyFactoryInterceptorTestCase.class);
+
+   /**
+    *
+    */
+   private static final String KEY = "SomeKey";
+
+   /**
+     * Test that the local calls are handled locally.
+     * @throws Exception
+     */
+   @Test
+   public void testIsLocal() throws Exception
+   {
+
+      // Too AOP oriented stuff, since the IsLocalProxyFactoryInterceptor is heavily
+      // into AOP.
+      // Had to copy over from
+      // org.jboss.ejb3.proxy.impl.objectfactory.ProxyObjectFactory#getObjectInstance
+
+      // Create a POJI Proxy to the Registrar
+
+      // Intentionally add a dummy NotToBeInvokedInterceptor to check whether the IsLocalProxyFactoryInterceptor
+      // passes the call to the next interceptor. If it's passed then it indicates that the call was (incorrectly) considered
+      // remote
+      Interceptor[] interceptors =
+      {IsLocalProxyFactoryInterceptor.singleton, new NotToBeInvokedInterceptor()};
+      PojiProxy handler = new PojiProxy(KEY, null, interceptors);
+      Class<?>[] interfaces = new Class<?>[]
+      {Calculator.class};
+      // create the proxy
+      Calculator calculator = (Calculator) Proxy.newProxyInstance(interfaces[0].getClassLoader(), interfaces, handler);
+      // register with dispatcher too, since the IsLocalProxyFactoryInterceptor
+      // looks for the key in the dispatcher
+      Dispatcher.singleton.registerTarget(KEY, new CalculatorImpl());
+
+      try
+      {
+         int result = calculator.add(1, 2);
+         logger.info("Successfully invoked method. Result = " + result);
+         Assert.assertEquals("Incorrect result from calculator", result, 3);
+      }
+      catch (IllegalInvocationException iie)
+      {
+         logger.error("Local call was considered as remote", iie);
+         // If the call was treated as remote then the dummy NotToBeInvokedInterceptor
+         // will be called and it would throw a IllegalInvocationException
+         Assert
+               .fail("A local invocation was treated as a remote invocation by " + IsLocalProxyFactoryInterceptor.class);
+      }
+
+   }
+
+}




More information about the jboss-cvs-commits mailing list