1 2 Previous Next 24 Replies Latest reply on Dec 17, 2008 6:50 AM by jaikiran pai

    EJBTHREE-1396 MockServer must report startup / shutdown

    jaikiran pai Master

      I have introduced a MockServerMonitor which has APIs for waiting for the MockServer to startup (and shutdown). It internally uses sockets to communicate with the MockServer which runs in a separate JVM.

      * The RemoteAccessTestCase will use the startMonitoring() API on the MockServerMonitor to initialize the monitor.
      * Later after the test case creates and new "process" to start the server, it invokes the waitForServerStartup() API (in place of the Thread.sleep()) which is a blocking call and waits until the MockServer starts
      * The MockServer inturn when starting up (and at other important state changes) sends out notifications on the socket (which is monitored by the MockServerMonitor) about its status.
      * The MockServer will send notifications only if monitoring is enabled, which is decided by the arguments passed to the MockServer.

      Here are the changes that were introduced as part of this:

      (Changes to) MockServer:

      Index: src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServer.java
      ===================================================================
      --- src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServer.java (revision 80547)
      +++ src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServer.java (working copy)
      @@ -1,6 +1,11 @@
       package org.jboss.ejb3.test.proxy.remoteaccess;
      
      +import java.io.DataOutputStream;
      +import java.io.IOException;
      +import java.net.InetAddress;
      +import java.net.Socket;
       import java.net.URL;
      +import java.net.UnknownHostException;
      
       import org.jboss.aop.AspectManager;
       import org.jboss.aop.AspectXmlLoader;
      @@ -13,6 +18,7 @@
       import org.jboss.ejb3.test.proxy.common.ejb.sfsb.MyStatefulBean;
       import org.jboss.ejb3.test.proxy.common.ejb.slsb.MyStatelessBean;
       import org.jboss.logging.Logger;
      +import org.jboss.xb.binding.metadata.AddMethodMetaData;
      
       /**
       * MockServer
      @@ -35,6 +41,18 @@
       private static MockServer server;
      
       private static final String FILENAME_EJB3_INTERCEPTORS_AOP = "ejb3-interceptors-aop.xml";
      +
      + public static int SERVER_STARTING = 1;
      +
      + public static int SERVER_STARTED = 2;
      +
      + public static int SERVER_STOPPING = 9;
      +
      + public static int SERVER_STOPPED = 10;
      +
      + private Socket socket;
      +
      + private int monitoringPort = -1;
      
       // --------------------------------------------------------------------------------||
       // Instance Members ---------------------------------------------------------------||
      @@ -72,7 +90,7 @@
       {
      
       // Assert test class passed in
      - assert args.length == 1 : "String fully-qualified name of test class is the required first argument";
      + assert args.length > 0 : "(Minimally) String fully-qualified name of test class is the required first argument";
      
       // Get Test Class
       String testClassname = args[0];
      @@ -88,6 +106,10 @@
      
       // Create a new Launcher
       MockServer launcher = new MockServer(testClass);
      + // If any monitoring port is specified, then set the port accordingly
      + if (args.length > 1) {
      + launcher.addMonitoringSupport(Integer.parseInt(args[1]));
      + }
       MockServer.setServer(launcher);
      
       // Initialize the launcher in a new Thread
      
      +
      + /**
      + * Initializes this {@link MockServer} to support monitoring
      + *
      + * @param port The port on which the status will be sent
      + */
      + protected void addMonitoringSupport(int port)
      + {
      + this.monitoringPort = port;
      + try
      + {
      + this.socket = new Socket(InetAddress.getByName("localhost"),this.monitoringPort);
      + log.info("MockServer will send notifications to monitor on port " + this.monitoringPort);
      + }
      + catch (Exception e)
      + {
      + throw new RuntimeException("Could not add monitoring support to the MockServer: ",e);
      + }
      +
      +
      +
      + }
      +
      + /**
      + * Publishes a status to the <code>socket</code> <br/>
      + * This status can then be used by any "monitors"
      + *
      + * @param status The status to publish
      + */
      + protected void publishStatus(int status)
      + {
      + DataOutputStream dataOutputStream;
      + try
      + {
      + dataOutputStream = new DataOutputStream(this.socket.getOutputStream());
      + dataOutputStream.writeInt(status);
      + }
      + catch (IOException ioe)
      + {
      + throw new RuntimeException("Error while sending status = " + status,ioe);
      + }
      +
      + }
      
      + /**
      + * Returns true if this {@link MockServer} supports monitoring.
      + * Else returns false
      + *
      + * @return
      + */
      + protected boolean hasMonitoringSupport()
      + {
      + if (this.monitoringPort != -1)
      + {
      + return true;
      + }
      + return false;
       }
      -
       // --------------------------------------------------------------------------------||
       // Inner Classes ------------------------------------------------------------------||
       // --------------------------------------------------------------------------------||
      @@ -185,13 +263,38 @@
       public void run()
       {
       // Initialize
      + boolean initialized = false;
       try
       {
      + // notify that the server is starting
      + if (this.getLauncher().hasMonitoringSupport()) {
      + this.getLauncher().publishStatus(SERVER_STARTING);
      + }
      +
       this.getLauncher().initialize();
      + initialized = true;
       }
       catch (Throwable e)
       {
       throw new RuntimeException("Could not initialize " + this.getLauncher(), e);
      + } finally
      + {
      + if (this.getLauncher().hasMonitoringSupport())
      + {
      + if (initialized)
      + {
      + // if successfully initialized then publish a "Started" notification
      + // This notification could then be used by the "monitor"
      + this.getLauncher().publishStatus(SERVER_STARTED);
      + }
      + else
      + {
      + // set the status to stopped
      + // TODO: Do we need a separate status like "NOT_STARTED" in
      + // addition to "STOPPED"
      + this.getLauncher().publishStatus(SERVER_STOPPED);
      + }
      + }
       }
      
       // Run
      @@ -230,6 +333,24 @@
       public void run()
       {
       getServer().bootstrap.shutdown();
      + try {
      + if (getServer().hasMonitoringSupport())
      + {
      + getServer().publishStatus(SERVER_STOPPED);
      + }
      + } finally {
      + if (getServer().socket != null) {
      + try
      + {
      + getServer().socket.close();
      + }
      + catch (IOException ioe)
      + {
      + // Ignore
      + log.debug("Error closing socket during shutdown of MockServer: " + ioe);
      + }
      + }
      + }
       }
       }
      
      @@ -267,4 +388,4 @@
       MockServer.server = server;
       }
      
      -}
      \ No newline at end of file
      +}
      


      The new MockServerMonitor:

      Index: src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServerMonitor.java
      ===================================================================
      --- src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServerMonitor.java (revision 0)
      +++ src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/MockServerMonitor.java (revision 0)
      @@ -0,0 +1,212 @@
      +/*
      + * 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.ejb3.test.proxy.remoteaccess;
      +
      +import java.io.DataInputStream;
      +import java.io.IOException;
      +import java.net.InetAddress;
      +import java.net.ServerSocket;
      +import java.net.Socket;
      +import java.net.UnknownHostException;
      +
      +import org.jboss.logging.Logger;
      +
      +/**
      + * MockServerMonitor
      + *
      + * Monitors the startup/shutdown of the {@link MockServer} <br/>
      + *
      + * Internally creates a {@link ServerSocket} and listens for the
      + * {@link MockServer} to post its status.
      + *
      + * @author Jaikiran Pai
      + * @version $Revision: $
      + */
      +public class MockServerMonitor
      +{
      +
      + /**
      + * Instance of logger
      + */
      + private static Logger logger = Logger.getLogger(MockServerMonitor.class);
      +
      + /**
      + * The port number on which the {@link MockServer}
      + * will be monitored for status
      + */
      + private int port;
      +
      + /**
      + * Localhost
      + */
      + private InetAddress localServer;
      +
      + /**
      + * Flag to indicate whether the monitor has been initialized
      + */
      + private boolean inited;
      +
      + /**
      + * Used for communicating with the {@link MockServer} which runs
      + * in a separate JVM
      + */
      + private ServerSocket serverSocket;
      +
      + /**
      + * Constructor
      + *
      + * @param port
      + */
      + public MockServerMonitor(int port)
      + {
      + this.port = port;
      + try
      + {
      + this.localServer = InetAddress.getByName("localhost");
      + }
      + catch (UnknownHostException unhe)
      + {
      + String msg = "Could not create the mockserver monitor. Monitoring will be disabled.";
      + logger.error(msg, unhe);
      + throw new RuntimeException(unhe);
      + }
      + }
      +
      + /**
      + * Initialize for monitoring the {@link MockServer} <br/>
      + *
      + * This will create a {@link ServerSocket} to listen on the
      + * <code>port</code> passed to the {@link MockServerMonitor#MockServerMonitor(int)}
      + * constructor
      + */
      + public void startMonitoring()
      + {
      + try
      + {
      + this.serverSocket = new ServerSocket(this.port, 1, this.localServer);
      + // set a flag indicating successful initialization
      + this.inited = true;
      + logger.info("Started to monitor MockServer on " + this.localServer + ":" + this.port);
      + }
      + catch (IOException ioe)
      + {
      + throw new RuntimeException("Could not start monitoring the MockServer on " + this.port, ioe);
      +
      + }
      + }
      +
      + /**
      + * Stop monitoring the {@link MockServer} <br/>
      + *
      + * Stops the {@link ServerSocket} and does any related
      + * cleanup
      + */
      + public void stopMonitoring()
      + {
      + if (this.serverSocket == null)
      + {
      + // do nothing
      + return;
      + }
      + try
      + {
      + this.serverSocket.close();
      + this.inited = false;
      + }
      + catch (IOException ioe)
      + {
      + throw new RuntimeException("Could not stop monitoring the MockServer on " + this.port, ioe);
      +
      + }
      + }
      +
      + /**
      + * Wait for the {@link MockServer} to startup
      + */
      + public void waitForServerStartup()
      + {
      + if (inited)
      + {
      + Socket client = null;
      + try
      + {
      + logger.debug("Connecting... " + this.port);
      +
      + // We need to add a timeout to the monitoring, to handle cases where
      + // the control probably never reached a point in MockServer where it
      + // could allow the monitor to connect. We wouldn't want this monitor
      + // to wait forever.
      +
      + // the timeout can be made configurable
      + this.serverSocket.setSoTimeout(10000);
      + // Accept the MockServer connection
      + client = this.serverSocket.accept();
      +
      + logger.debug("Connected... " + this.port);
      +
      + DataInputStream dataInputStream = new DataInputStream(client.getInputStream());
      + int mockServerStatus = -1;
      + // Start receiving the status
      + while (mockServerStatus != MockServer.SERVER_STARTED)
      + {
      + logger.debug("Reading MockServer status on port " + this.port);
      + mockServerStatus = dataInputStream.readInt();
      + logger.debug("MockServer returned status = " + mockServerStatus);
      + }
      + logger.info("MockServer is in started state");
      + return;
      +
      + }
      + catch (IOException ioe)
      + {
      + logger.error("Error while monitoring the MockServer for startup on port " + this.port, ioe);
      + throw new RuntimeException("MockServer is probably not started: ", ioe);
      + }
      + finally
      + {
      + // house-keeping
      + if (client != null)
      + {
      + try
      + {
      + client.close();
      + }
      + catch (IOException e)
      + {
      + // Ignore
      + logger.debug("Could not close socket");
      + }
      + }
      +
      + }
      + }
      + }
      +
      + /**
      + * Wait for the {@link MockServer} to completely shutdown
      + */
      + public void waitForServerShutdown()
      + {
      + // No implementation yet. The testcase currently does not
      + // wait for shutdown. If required, we can add the implementation
      + }
      +}
      
      
      


      (Changes to the) RemoteAccessTestCase:

      Index: src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/unit/RemoteAccessTestCase.java
      ===================================================================
      --- src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/unit/RemoteAccessTestCase.java (revision 80547)
      +++ src/test/java/org/jboss/ejb3/test/proxy/remoteaccess/unit/RemoteAccessTestCase.java (working copy)
      @@ -37,6 +37,7 @@
       import org.jboss.ejb3.test.proxy.common.ejb.slsb.MyStatelessRemote;
       import org.jboss.ejb3.test.proxy.remoteaccess.JndiPropertiesToJndiRemotePropertiesHackCl;
       import org.jboss.ejb3.test.proxy.remoteaccess.MockServer;
      +import org.jboss.ejb3.test.proxy.remoteaccess.MockServerMonitor;
       import org.jboss.logging.Logger;
       import org.junit.AfterClass;
       import org.junit.BeforeClass;
      @@ -82,6 +83,8 @@
       private static final String JNDI_NAME_SFSB_REMOTE = "MyStatefulBean/remote";
      
       private static Process remoteProcess;
      +
      + private static MockServerMonitor mockServerMonitor;
      
       private static Context context;
      
      @@ -181,11 +184,24 @@
       // Replace the CL
       Thread.currentThread().setContextClassLoader(oldLoader);
      
      + // Start the MockServerMonitor
      + // TODO: Make the port configurable
      + int monitoringPort = 12345;
      + mockServerMonitor = new MockServerMonitor(monitoringPort);
      + mockServerMonitor.startMonitoring();
      +
       // Start Server
      - RemoteAccessTestCase.invokeRemoteMockServerProcess(RemoteAccessTestCase.class.getName());
      + RemoteAccessTestCase.invokeRemoteMockServerProcess(new String[] {RemoteAccessTestCase.class.getName(),Integer.toString(monitoringPort)});
      
       // Wait for Server to start
      - Thread.sleep(5000);
      + log.info("Waiting for MockServer to start");
      + long start = System.currentTimeMillis();
      +
      + mockServerMonitor.waitForServerStartup();
      +
      + long end = System.currentTimeMillis();
      + log.info("MockServer started in " + (end-start) + " milli sec.");
      +
       }
      
       /**
      @@ -202,6 +218,8 @@
       Process p = RemoteAccessTestCase.getRemoteProcess();
       p.destroy();
      
      + mockServerMonitor.stopMonitoring();
      +
       }
      
       // --------------------------------------------------------------------------------||
      @@ -214,7 +232,7 @@
       * @param argument
       * @throws Throwable
       */
      - protected static void invokeRemoteMockServerProcess(String argument) throws Throwable
      + protected static void invokeRemoteMockServerProcess(String[] arguments) throws Throwable
       {
       // Get the current System Properties and Environment Variables
       String javaHome = System.getenv(RemoteAccessTestCase.ENV_VAR_JAVAHOME);
      @@ -243,7 +261,8 @@
       command.append(File.separatorChar);
       command.append(RemoteAccessTestCase.EXECUTABLE_JAVA);
       command.append(" -cp "); // Classpath
      -
      + command.append("\"");
      +
       command.append(classes);
       command.append(File.pathSeparatorChar);
       command.append(testClasses);
      @@ -251,10 +270,16 @@
       command.append(conf);
       command.append(File.pathSeparatorChar);
       command.append(depCp); // Dependency CP
      + command.append("\"");
      +
       command.append(" -ea "); // Enable Assertions
       command.append(MockServer.class.getName());
       command.append(' ');
      - command.append(argument); // Argument
      + for (int i=0; i < arguments.length; i++) {
      + command.append(arguments); // Argument
       + command.append(' ');
       + }
       +
      
       // Create a Remote Launcher
       String cmd = command.toString();
      
      
      
      


      Any review comments/suggestions are welcome. I'll attach a patch to the JIRA if this looks like a valid start at implementing this enhancement.


        • 1. Re: EJBTHREE-1396 MockServer must report startup / shutdown
          jaikiran pai Master

          Furthermore, this patch includes a fix to a minor issue which i observed on my local (Windows) setup. I have my Maven repository at C:\Documents and Settings\jaikiran_pai\.m2\repository. Note the space character in the folder names. This used to always fail on my setup with:

          14:46:59,056 INFO [RemoteAccessTestCase] Launching in separate process: C:\jdk1.5.0_10\bin\java -cp C:\Documents and Settings\jaikiran_pai\.m2\repository\apache-log4j\log4j\1.2.14\log4j-1.2.14.jar;C:\Documents and Settings\jaikiran_pai\.m2\repository\apache-xerces\xercesImpl\2.9.1\xercesImpl-2.9.1.jar; [...the rest of the classpath] -ea org.jboss.ejb3.test.proxy.remoteaccess.MockServer org.jboss.ejb3.test.proxy.remoteaccess.unit.RemoteAccessTestCase
          java.lang.NoClassDefFoundError: and
          
          Exception in thread "main" @SLTests run: 4, Failures: 0, Errors: 4, Skipped: 0, Time elapsed: 29.563 sec <<< FAILURE!
          


          The patch that i posted includes the fix to enclose the classpath in double quotes:

          @@ -243,7 +261,8 @@
           command.append(File.separatorChar);
           command.append(RemoteAccessTestCase.EXECUTABLE_JAVA);
           command.append(" -cp "); // Classpath
          -
          + command.append("\"");
          +
           command.append(classes);
           command.append(File.pathSeparatorChar);
           command.append(testClasses);
          @@ -251,10 +270,16 @@
           command.append(conf);
           command.append(File.pathSeparatorChar);
           command.append(depCp); // Dependency CP
          + command.append("\"");
          


          • 2. Re: EJBTHREE-1396 MockServer must report startup / shutdown
            Andrew Rubinger Master

            Figured you're waiting on pins and needles for my opinion. ;)

            * Methods like "hasMonitoringSupport" violate OO practices; this is what inheritance is for. You can ensure that a MockServer has this support by removing "addMonitoringSupport(int port)" in favor of another argument to a MonitorableMockServer constructor if indeed being "Monitorable" is a separate add-on capability (which might even come with its own interface).

            * Constants like SERVER_STARTING should be marked "final"?

            * MockServerMonitor has hardcoded "localhost" used by the ServerSocket. If we've gotta specify a port, might as well specify a host bind address (to bind to 2 unique hosts using same port for example)

            * In MockServerMonitor.waitForServerStartup(), there's a "while not started" loop. Let's throw a Thread.sleep(100) or something in there as to relax the CPU a bit

            * RemoteAccessTestCase now has "mockServerMonitor.waitForServerStartup();", which will block indefinitely - what if server does not start? Recommend making a "private volatile boolean remoteServerStarted" field, spawning off the check to "waitForServerStartup" into a j.u.c.FutureTask, and then call "getResult()" on it with a sensible timeout value. The FutureTask's job would be to set the "remoteServerStarted" to true, and then the RemoteAccessTestCase can poll for that. In the case of a timeout of the FutureTask, throw an exception and fail the test.

            * I put a static instance of MockServer *in* MockServer? It'd make me smile if you could remove that so we can actually start up more than one MockServer. This shouldn't be a Singleton, and even if it was, that's just bad implementation.

            S,
            ALR

            • 3. Re: EJBTHREE-1396 MockServer must report startup / shutdown
              Carlo de Wolf Master

               

              "ALRubinger" wrote:
              * In MockServerMonitor.waitForServerStartup(), there's a "while not started" loop. Let's throw a Thread.sleep(100) or something in there as to relax the CPU a bit

              * RemoteAccessTestCase now has "mockServerMonitor.waitForServerStartup();", which will block indefinitely - what if server does not start? Recommend making a "private volatile boolean remoteServerStarted" field, spawning off the check to "waitForServerStartup" into a j.u.c.FutureTask, and then call "getResult()" on it with a sensible timeout value. The FutureTask's job would be to set the "remoteServerStarted" to true, and then the RemoteAccessTestCase can poll for that. In the case of a timeout of the FutureTask, throw an exception and fail the test

              This has nothing to do with CPU, it's a blocking I/O case.

              Use NIO or Remoting 3 here.

              • 4. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                Andrew Rubinger Master

                 

                "wolfc" wrote:
                This has nothing to do with CPU, it's a blocking I/O case.


                Whoopsie! Missed that "readInt" bit.

                Point, Carlo.

                S,
                ALR

                • 5. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                  Andrew Rubinger Master

                   

                  "ALRubinger" wrote:
                  RemoteAccessTestCase now has "mockServerMonitor.waitForServerStartup();", which will block indefinitely


                  This point is still valid though. If the server never posts the signal that its up, the test will hang.

                  S,
                  ALR

                  • 6. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                    jaikiran pai Master

                    Thanks everyone for your time and the comments.

                    "ALRubinger" wrote:
                    * Constants like SERVER_STARTING should be marked "final"?


                    Agreed. That was my silly mistake.

                    "ALRubinger" wrote:

                    * MockServerMonitor has hardcoded "localhost" used by the ServerSocket. If we've gotta specify a port, might as well specify a host bind address (to bind to 2 unique hosts using same port for example)


                    Sure, will change it to allow the host bind address to be a parameter.

                    I'll consider the rest of the comments too:

                    - Not good OO pratice
                    - Chances of the test case waiting indefinitely
                    - The static instance of MockServer in itself.

                    Thanks again, for the inputs :)




                    • 7. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                      jaikiran pai Master

                      Based on these inputs, i have refactored a lot of the code including the RemoteAccessTestCase. Here's the details:

                      * I have introduced a MockServerController which has APIs to start and stop the MockServer

                      /**
                       * Creates a remote process (JVM) to launch the {@link MockServer}
                       * and then sends a {@link MockServerRequest#START} request to start the
                       * server
                       *
                       * @param arguments The arguments that will be passed to the {@link MockServer}
                       * as JVM program arguments
                       *
                       * @throws Throwable
                       */
                       public void startServer(String[] arguments) throws Throwable
                      
                      
                      /**
                       * Sends a {@link MockServerRequest#STOP} request to the server
                       * and also kills the process in whic the server was running
                       *
                       * @see MockServerController#stopServer(boolean)
                       * @throws Throwable
                       */
                       public void stopServer() throws Throwable
                      
                      
                      
                      * The MockServerController is now responsible for creating the remote process and then issuing a MockServerRequest.START to start the server. This request will then be handled remotely by a MockServerInvocationHandler which inturn will invoke the start() API of the MockServer.

                      * MockServerController.startServer()/stopServer() is a blocking call (with a timeout).

                      * Support to start multiple MockServer in their own JVM is now available. One MockServerController can control one MockServer. So if multiple MockServer needs to be created, there will n such MockServerController, each controlling the corresponding server

                      * Individual test case will no longer be responsible for creating the remote (JVM) process. Instead they will instantiate a MockServerController

                      /**
                       * Constructor <br>
                       * Creates a {@link Client} to send requests to the remote {@link MockServer}
                       *
                       * @param host The host on which the {@link MockServer} is available
                       * @param port The port on which the {@link MockServer} is listening
                       */
                       public MockServerController(String host, int port)
                      

                      and then invoke the startServer API (and later stopServer)

                      * These new changes now use Remoting 2.x (current version being used in the project) framework.




                      • 8. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                        jaikiran pai Master

                        Here's how the code looks now. Let me know if you would want a "diff".

                        RemoteAccessTestCase

                        package org.jboss.ejb3.test.proxy.remoteaccess.unit;
                        
                        import static org.junit.Assert.assertEquals;
                        import static org.junit.Assert.assertTrue;
                        
                        import javax.naming.Context;
                        import javax.naming.InitialContext;
                        
                        import org.jboss.ejb3.test.proxy.common.ejb.sfsb.MyStatefulRemoteBusiness;
                        import org.jboss.ejb3.test.proxy.common.ejb.slsb.MyStatelessRemote;
                        import org.jboss.ejb3.test.proxy.remoteaccess.JndiPropertiesToJndiRemotePropertiesHackCl;
                        import org.jboss.ejb3.test.proxy.remoteaccess.MockServerController;
                        import org.jboss.logging.Logger;
                        import org.junit.AfterClass;
                        import org.junit.BeforeClass;
                        import org.junit.Test;
                        
                        /**
                         * RemoteAccessTestCase
                         *
                         * @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
                         * @version $Revision: $
                         */
                        
                        public class RemoteAccessTestCase
                        {
                         // --------------------------------------------------------------------------------||
                         // Class Members ------------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         private static final Logger log = Logger.getLogger(RemoteAccessTestCase.class);
                        
                         private static final String JNDI_NAME_SLSB_LOCAL = "MyStatelessBean/local";
                        
                         private static final String JNDI_NAME_SLSB_REMOTE = "MyStatelessBean/remote";
                        
                         private static final String JNDI_NAME_SFSB_REMOTE = "MyStatefulBean/remote";
                        
                         private static MockServerController mockServerController;
                        
                         /**
                         * The server host on which the MockServer will be available for requests
                         */
                         private static final String serverHost = "localhost";
                        
                         /**
                         * The server port on which the MockServer will be available for requests
                         */
                         private static final int serverPort = 12345;
                        
                         private static Context context;
                        
                         // --------------------------------------------------------------------------------||
                         // Instance Members ---------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         // --------------------------------------------------------------------------------||
                         // Tests --------------------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         /**
                         * Ensures that a SLSB Remote invocation succeeds
                         */
                         @Test
                         public void testStatelessSessionRemoteInvocation() throws Throwable
                         {
                         ..... // removed while posting
                         }
                        
                         /**
                         * Ensures that more than one SLSB Remote invocations succeed
                         */
                         @Test
                         public void testStatelessSessionDuplicateRemoteInvocations() throws Throwable
                         {
                         ..... // removed while posting
                         }
                        
                         /**
                         * Ensures that a SFSB Remote invocation succeeds
                         */
                         @Test
                         public void testStatefulSessionRemoteInvocation() throws Throwable
                         {
                         ..... // removed while posting
                        
                         }
                        
                         /**
                         * Ensures that more than one SFSB Remote invocations succeed
                         */
                         @Test
                         public void testStatefulSessionDuplicateRemoteInvocation() throws Throwable
                         {
                         ..... // removed while posting
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Lifecycle Methods --------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         /**
                         * Starts the MockServer
                         */
                         @BeforeClass
                         public static void beforeClass() throws Throwable
                         {
                         // Switch up to the hacky CL so that "jndi.properties" is not loaded, and uses instead "jndi-remote.properties"
                         ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
                         Thread.currentThread().setContextClassLoader(new JndiPropertiesToJndiRemotePropertiesHackCl());
                        
                         RemoteAccessTestCase.setContext(new InitialContext());
                        
                         // Replace the CL
                         Thread.currentThread().setContextClassLoader(oldLoader);
                        
                         // create a controller for mockserver
                         mockServerController = new MockServerController(serverHost, serverPort);
                        
                         // Start Server
                         long start = System.currentTimeMillis();
                         mockServerController.startServer(new String[]{RemoteAccessTestCase.class.getName()});
                         long end = System.currentTimeMillis();
                         log.info("MockServer started in " + (end - start) + " milli sec.");
                        
                         }
                        
                         /**
                         * Stops the MockServer
                         *
                         * @throws Throwable
                         */
                         @AfterClass
                         public static void afterClass() throws Throwable
                         {
                         mockServerController.stopServer();
                        
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Accessors / Mutators -----------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         public static Context getContext()
                         {
                         return context;
                         }
                        
                         protected static void setContext(Context context)
                         {
                         RemoteAccessTestCase.context = context;
                         }
                        
                        }
                        
                        


                        MockServerController

                        package org.jboss.ejb3.test.proxy.remoteaccess;
                        
                        import java.io.BufferedReader;
                        import java.io.File;
                        import java.io.FileReader;
                        import java.util.HashMap;
                        import java.util.Map;
                        
                        import org.jboss.ejb3.common.thread.RedirectProcessOutputToSystemOutThread;
                        import org.jboss.ejb3.test.proxy.remoteaccess.MockServer.MockServerRequest;
                        import org.jboss.logging.Logger;
                        import org.jboss.remoting.Client;
                        import org.jboss.remoting.InvokerLocator;
                        
                        /**
                         * MockServerController
                         *
                         * Controls the startup/shutdown of the {@link MockServer} <br/>
                         *
                         * @author Jaikiran Pai
                         * @version $Revision: $
                         */
                        public class MockServerController
                        {
                        
                         /**
                         * Instance of logger
                         */
                         private static Logger logger = Logger.getLogger(MockServerController.class);
                        
                         private static final String ENV_VAR_JAVAHOME = "JAVA_HOME";
                        
                         private static final String EXECUTABLE_JAVA = "bin" + File.separator + "java";
                        
                         private static final String LOCATION_BASEDIR = System.getProperty("basedir");
                        
                         private static final String LOCATION_TARGET = MockServerController.LOCATION_BASEDIR + File.separator + "target";
                        
                         private static final String LOCATION_TEST_CLASSES = MockServerController.LOCATION_TARGET + File.separator
                         + "tests-classes";
                        
                         private static final String LOCATION_CLASSES = MockServerController.LOCATION_TARGET + File.separator + "classes";
                        
                         private static final String LOCATION_CONF = MockServerController.LOCATION_BASEDIR + File.separator + "conf";
                        
                         private static final String FILENAME_DEPENDENCY_CP = MockServerController.LOCATION_TARGET + File.separator
                         + "cp.txt";
                        
                         /**
                         * Timeout in milli sec. for server startup/shutdown
                         */
                         private static final int TIMEOUT = 120000;
                        
                         /**
                         * The port number on which the {@link MockServer}
                         * is available for requests
                         */
                         private int port;
                        
                         /**
                         * The host on which the {@link MockServer}
                         * is available for requests
                         */
                         private String serverHost;
                        
                         /**
                         * Remote process in which the {@link MockServer} will run
                         */
                         private Process remoteProcess;
                        
                         /**
                         * {@link Client} for sending requests to the {@link MockServer}
                         */
                         private Client mockServerClient;
                        
                         /**
                         * Constructor <br>
                         * Creates a {@link Client} to send requests to the remote {@link MockServer}
                         *
                         * @param host The host on which the {@link MockServer} is available
                         * @param port The port on which the {@link MockServer} is listening
                         */
                         public MockServerController(String host, int port)
                         {
                         this.serverHost = host;
                         this.port = port;
                         String uri = null;
                         try
                         {
                         uri = "socket://" + this.serverHost + ":" + this.port;
                         InvokerLocator invokerLocator = new InvokerLocator(uri);
                         this.mockServerClient = new Client(invokerLocator);
                        
                         }
                         catch (Exception e)
                         {
                         throw new RuntimeException("Could not create server controller: ", e);
                         }
                        
                         }
                        
                         /**
                         * Creates a remote process (JVM) to launch the {@link MockServer}
                         * and then sends a {@link MockServerRequest#START} request to start the
                         * server
                         *
                         * @param arguments The arguments that will be passed to the {@link MockServer}
                         * as JVM program arguments
                         *
                         * @throws Throwable
                         */
                         public void startServer(String[] arguments) throws Throwable
                         {
                         // Along with the arguments that the client passes to the server,
                         // append the the serverHost and port number on which the mockserver is
                         // expected to listen
                         int numberOfArgs = arguments.length;
                         String[] processArgs = new String[numberOfArgs + 2];
                         System.arraycopy(arguments, 0, processArgs, 0, numberOfArgs);
                         // now append the server host and port
                         processArgs[processArgs.length - 2] = this.serverHost;
                         processArgs[processArgs.length - 1] = String.valueOf(this.port);
                        
                         createRemoteProcess(processArgs);
                        
                         sendStartRequestToServer();
                         }
                        
                         /**
                         * Sends a {@link MockServerRequest#STOP} request to the server
                         * and also kills the process in whic the server was running
                         *
                         * @see MockServerController#stopServer(boolean)
                         * @throws Throwable
                         */
                         public void stopServer() throws Throwable
                         {
                         stopServer(true);
                         logger.debug("Stopped the server and killed the remote process");
                        
                         }
                        
                         /**
                         * Sends a {@link MockServerRequest#STOP} request to the server
                         * and if the <code>killProcess</code> is true then it also kills
                         * the process in which the server was running.
                         *
                         * @param killProcess If true, kills the process in which the {@link MockServer}
                         * was running. Else, just sends a {@link MockServerRequest#STOP} request
                         * to the server.
                         * @throws Throwable
                         */
                         public void stopServer(boolean killProcess) throws Throwable
                         {
                         try
                         {
                         sendStopRequestToServer();
                         logger.debug("Stopped server");
                         // disconnect the client
                         this.mockServerClient.disconnect();
                        
                         }
                         finally
                         {
                         if (killProcess)
                         {
                         // destroy the remote process
                         this.remoteProcess.destroy();
                         logger.debug("Remote process killed");
                         }
                         }
                         }
                        
                         /**
                         * Sends a {@link MockServerRequest#STOP} to the server
                         *
                         * @throws Throwable
                         */
                         protected void sendStopRequestToServer() throws Throwable
                         {
                         this.mockServerClient.connect();
                         // set a timeout - The client will wait for this amount of time
                         // for the mockserver to shutdown
                         Map configParams = new HashMap();
                         configParams.put("timeout", String.valueOf(TIMEOUT));
                         Object serverStatus = this.mockServerClient.invoke(MockServerRequest.STOP, configParams);
                         logger.debug("Stop request returned Status = " + serverStatus);
                        
                         }
                        
                         /**
                         * Sends a {@link MockServerRequest#START} to the server
                         * @throws Throwable
                         */
                         protected void sendStartRequestToServer() throws Throwable
                         {
                         this.mockServerClient.connect();
                         // set a timeout - The client will wait for this amount of time
                         // for the mockserver to shutdown
                         Map configParams = new HashMap();
                         configParams.put("timeout", String.valueOf(TIMEOUT));
                         Object serverStatus = this.mockServerClient.invoke(MockServerRequest.START, configParams);
                         logger.info("Server started. Status = " + serverStatus);
                        
                         }
                        
                         /**
                         * Creates a new JVM process in which the {@link MockServer} will be active
                         *
                         *
                         * @param arguments The arguments to the passed to the {@link MockServer}
                         *
                         * @throws Throwable
                         */
                         private void createRemoteProcess(String arguments[]) throws Throwable
                         {
                         // Get the current System Properties and Environment Variables
                         String javaHome = System.getenv(MockServerController.ENV_VAR_JAVAHOME);
                         String conf = MockServerController.LOCATION_CONF;
                         String testClasses = MockServerController.LOCATION_TEST_CLASSES;
                         String classes = MockServerController.LOCATION_CLASSES;
                        
                         // Get the contents of the dependency classpath file
                         String dependencyClasspathFilename = MockServerController.FILENAME_DEPENDENCY_CP;
                         File dependencyClasspath = new File(dependencyClasspathFilename);
                         assert dependencyClasspath.exists() : "File " + dependencyClasspathFilename
                         + " is required to denote the dependency CP";
                         BufferedReader reader = new BufferedReader(new FileReader(dependencyClasspath));
                         StringBuffer contents = new StringBuffer();
                         String line = null;
                         while ((line = reader.readLine()) != null)
                         {
                         contents.append(line);
                         contents.append(System.getProperty("line.separator"));
                         }
                         String depCp = contents.toString().trim();
                        
                         // Build the command
                         StringBuffer command = new StringBuffer();
                         command.append(javaHome); // JAVA_HOME
                         command.append(File.separatorChar);
                         command.append(MockServerController.EXECUTABLE_JAVA);
                         command.append(" -cp "); // Classpath
                         command.append("\"");
                        
                         command.append(classes);
                         command.append(File.pathSeparatorChar);
                         command.append(testClasses);
                         command.append(File.pathSeparatorChar);
                         command.append(conf);
                         command.append(File.pathSeparatorChar);
                         command.append(depCp); // Dependency CP
                         command.append("\"");
                        
                         command.append(" -ea "); // Enable Assertions
                         command.append(MockServer.class.getName());
                         command.append(' ');
                         for (int i = 0; i < arguments.length; i++)
                         {
                         command.append(arguments); // Argument
                         command.append(' ');
                         }
                        
                         // Create a Remote Launcher
                         String cmd = command.toString();
                         String[] cmds = cmd.split(" ");
                         ProcessBuilder builder = new ProcessBuilder();
                         builder.command(cmds);
                         builder.redirectErrorStream(true);
                         File pwd = new File(MockServerController.LOCATION_BASEDIR);
                         assert pwd.exists() : "Present working directory for execution of remote process, " + pwd.getAbsolutePath()
                         + ", could not be found.";
                         logger.debug("Remote Process working directory: " + pwd.getAbsolutePath());
                         builder.directory(pwd);
                         logger.info("Launching in separate process: " + cmd);
                         try
                         {
                         this.remoteProcess = builder.start();
                         logger.info("Remote process = " + this.remoteProcess);
                         // Redirect output from the separate process
                         new RedirectProcessOutputToSystemOutThread(this.remoteProcess).start();
                        
                         }
                         catch (Throwable t)
                         {
                         throw new RuntimeException("Could not execute remote process", t);
                         }
                        
                         }
                        
                         }
                        
                        
                        


                        MockServer

                        package org.jboss.ejb3.test.proxy.remoteaccess;
                        
                        import java.net.URL;
                        
                        import org.jboss.aop.AspectManager;
                        import org.jboss.aop.AspectXmlLoader;
                        import org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar;
                        import org.jboss.ejb3.common.registrar.spi.Ejb3RegistrarLocator;
                        import org.jboss.ejb3.test.mc.bootstrap.EmbeddedTestMcBootstrap;
                        import org.jboss.ejb3.test.proxy.common.Utils;
                        import org.jboss.ejb3.test.proxy.common.container.StatefulContainer;
                        import org.jboss.ejb3.test.proxy.common.container.StatelessContainer;
                        import org.jboss.ejb3.test.proxy.common.ejb.sfsb.MyStatefulBean;
                        import org.jboss.ejb3.test.proxy.common.ejb.slsb.MyStatelessBean;
                        import org.jboss.logging.Logger;
                        import org.jboss.remoting.InvokerLocator;
                        import org.jboss.remoting.ServerInvocationHandler;
                        import org.jboss.remoting.transport.Connector;
                        
                        /**
                         * MockServer
                         *
                         * Launches a new MC Bootstrap, EJB Containers, and performs
                         * all initialization to mock a remote server environment
                         *
                         * @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
                         * @version $Revision: $
                         */
                        public class MockServer
                        {
                        
                         // --------------------------------------------------------------------------------||
                         // Class Members ------------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         private static final Logger log = Logger.getLogger(MockServer.class);
                        
                         /**
                         * Invocation request to the MockServer will be handler by this
                         * invocation handler
                         */
                         private ServerInvocationHandler mockServerInvocationHandler;
                        
                         private static final String FILENAME_EJB3_INTERCEPTORS_AOP = "ejb3-interceptors-aop.xml";
                        
                         /**
                         * Various possible server status
                         */
                         public enum MockServerStatus
                         {
                         STARTED, STOPPED
                         }
                        
                         /**
                         *
                         * Various possible server requests
                         */
                         public enum MockServerRequest
                         {
                         START, STOP
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Instance Members ---------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         private EmbeddedTestMcBootstrap bootstrap;
                        
                         /**
                         * Accept requests from client using this {@link Connector}
                         */
                         private Connector remoteConnector;
                        
                         /**
                         * The current state of the server
                         */
                         private MockServerStatus currentStatus = MockServerStatus.STOPPED;
                        
                         /**
                         * The Test Class using this launcher
                         */
                         private Class<?> testClass;
                        
                         // --------------------------------------------------------------------------------||
                         // Constructor --------------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         /**
                         * Constructor
                         * Configures and creates a socket based {@link Connector} which will
                         * accept (start/stop) requests from client
                         */
                         public MockServer(Class<?> testClass, String serverHost, int port)
                         {
                         this.setTestClass(testClass);
                         String uri = "socket://" + serverHost + ":" + port;
                         try
                         {
                         InvokerLocator invokerLocator = new InvokerLocator(uri);
                        
                         this.remoteConnector = new Connector(invokerLocator);
                         this.remoteConnector.create();
                         this.mockServerInvocationHandler = new MockServerInvocationHandler(this);
                         this.remoteConnector.addInvocationHandler("EJB3Test", this.mockServerInvocationHandler);
                        
                         }
                         catch (Exception e)
                         {
                         throw new RuntimeException("Could not start server at " + uri, e);
                         }
                        
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Main ---------------------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         /**
                         * Runtime Entry Point
                         *
                         * @param args
                         */
                         public static void main(String... args)
                         {
                        
                         // Assert test class passed in
                         assert args.length > 2 : "Parameters requried (in that order): <Fully qualified test case name> <serverBindAddress> <serverPort> ";
                        
                         // Get Test Class
                         String testClassname = args[0];
                         Class<?> testClass = null;
                         try
                         {
                         testClass = Class.forName(testClassname);
                         }
                         catch (ClassNotFoundException cnfe)
                         {
                         throw new RuntimeException("Specified Test Class, \"" + testClassname + "\" could not be found", cnfe);
                         }
                        
                         // Create a new Launcher
                         // the serverBindAddress and the port are always the last two arguments
                         MockServer launcher = new MockServer(testClass,args[args.length - 2],Integer.parseInt(args[args.length -1]));
                         try
                         {
                         // Ready to receive (start/stop) requests
                         launcher.acceptRequests();
                         }
                         catch (Throwable e)
                         {
                         throw new RuntimeException("Exception while waiting for requests ",e);
                         }
                        
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Functional Methods -------------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         /**
                         * Initializes the instance by starting up an MC Bootstrap,
                         * deploying relevant *-beans.xml, creating and installing EJB Containers
                         */
                         protected void initialize() throws Throwable
                         {
                         // Create and set a new MC Bootstrap
                         this.setBootstrap(EmbeddedTestMcBootstrap.createEmbeddedMcBootstrap());
                        
                         // Add a Shutdown Hook
                         //Runtime.getRuntime().addShutdownHook(new ShutdownHook());
                        
                         // Bind the Ejb3Registrar
                         Ejb3RegistrarLocator.bindRegistrar(new Ejb3McRegistrar(bootstrap.getKernel()));
                        
                         // Switch up to the hacky CL so that "jndi.properties" is not loaded
                         ClassLoader olderLoader = Thread.currentThread().getContextClassLoader();
                         Thread.currentThread().setContextClassLoader(new JndiPropertiesToJnpserverPropertiesHackCl());
                        
                         // Deploy *-beans.xml
                         this.getBootstrap().deploy(this.getTestClass());
                        
                         // Load ejb3-interceptors-aop.xml into AspectManager
                         ClassLoader cl = Thread.currentThread().getContextClassLoader();
                         URL url = cl.getResource(FILENAME_EJB3_INTERCEPTORS_AOP);
                         if (url == null)
                         {
                         throw new RuntimeException("Could not load " + AspectManager.class.getSimpleName()
                         + " with definitions from XML as file " + FILENAME_EJB3_INTERCEPTORS_AOP + " could not be found");
                         }
                         AspectXmlLoader.deployXML(url);
                        
                         // Restore old CL
                         Thread.currentThread().setContextClassLoader(olderLoader);
                        
                         // Create a SLSB Container
                         StatelessContainer slsbContainer = Utils.createSlsb(MyStatelessBean.class);
                         log.info("Created SLSB Container: " + slsbContainer.getName());
                        
                         // Create a SFSB Container
                         StatefulContainer sfsbContainer = Utils.createSfsb(MyStatefulBean.class);
                         log.info("Created SFSB Container: " + sfsbContainer.getName());
                        
                         // Install into MC
                         this.getBootstrap().installInstance(slsbContainer.getName(), slsbContainer);
                         this.getBootstrap().installInstance(sfsbContainer.getName(), sfsbContainer);
                        
                         }
                        
                         /**
                         * Starts the server <br>
                         *
                         * @throws IllegalStateException If the server is not in {@link MockServerStatus.STOPPED}
                         * state
                         * @throws Throwable
                         */
                         public void start() throws Throwable
                         {
                         // Server will be started only if current state is STOPPED
                         if (!this.currentStatus.equals(MockServerStatus.STOPPED))
                         {
                         throw new IllegalStateException("Cannot start MockServer when its in " + getStatus() + " state");
                         }
                         initialize();
                         this.currentStatus = MockServerStatus.STARTED;
                         log.info("MockServer started");
                         }
                        
                         /**
                         * Stops the server <br>
                         *
                         * @throws IllegalStateException If the server is not in {@link MockServerStatus.STARTED}
                         * state
                         */
                         public void stop()
                         {
                         // Server will be stopped only if current state is STARTED
                         if (!this.currentStatus.equals(MockServerStatus.STARTED))
                         {
                         throw new IllegalStateException("Cannot stop MockServer when its in " + getStatus() + " state");
                         }
                         this.bootstrap.shutdown();
                         this.currentStatus = MockServerStatus.STOPPED;
                         log.info("MockServer stopped");
                        
                         // Note: Do not stop the Connector which is waiting for clients to
                         // connect. Letting the Connector remain in waiting state will allow
                         // clients to restart this MockServer by sending the MockServerRequest.START
                         // request again.
                         }
                        
                         /**
                         *
                         * @return Returns the current status of the server
                         */
                         public MockServerStatus getStatus()
                         {
                         return this.currentStatus;
                         }
                        
                         /**
                         * Start accepting requests <br>
                         * This is a blocking call and will wait for clients to connect
                         *
                         * @see {@link Connector#start()}
                         * @throws Throwable
                         */
                         protected void acceptRequests() throws Throwable
                         {
                         this.remoteConnector.start();
                         }
                        
                         /**
                         *
                         * @param serverInvocationHandler The {@link ServerInvocationHandler} to
                         * handle requests
                         */
                         protected void setInvocationHandler(ServerInvocationHandler serverInvocationHandler)
                         {
                         this.mockServerInvocationHandler = serverInvocationHandler;
                        
                         }
                        
                         // --------------------------------------------------------------------------------||
                         // Accessors / Mutators -----------------------------------------------------------||
                         // --------------------------------------------------------------------------------||
                        
                         public EmbeddedTestMcBootstrap getBootstrap()
                         {
                         return this.bootstrap;
                         }
                        
                         public void setBootstrap(EmbeddedTestMcBootstrap bootstrap)
                         {
                         this.bootstrap = bootstrap;
                         }
                        
                         public Class<?> getTestClass()
                         {
                         return testClass;
                         }
                        
                         public void setTestClass(Class<?> testClass)
                         {
                         this.testClass = testClass;
                         }
                        
                        
                        }
                        
                        


                        MockServerInvocationHandler

                        package org.jboss.ejb3.test.proxy.remoteaccess;
                        
                        import javax.management.MBeanServer;
                        
                        import org.jboss.ejb3.test.proxy.remoteaccess.MockServer.MockServerRequest;
                        import org.jboss.logging.Logger;
                        import org.jboss.remoting.InvocationRequest;
                        import org.jboss.remoting.ServerInvocationHandler;
                        import org.jboss.remoting.ServerInvoker;
                        import org.jboss.remoting.callback.InvokerCallbackHandler;
                        
                        /**
                         * MockServerInvocationHandler
                         *
                         * @author Jaikiran Pai
                         * @version $Revision: $
                         */
                        public class MockServerInvocationHandler implements ServerInvocationHandler
                        {
                        
                         private static Logger logger = Logger.getLogger(MockServerInvocationHandler.class);
                        
                         private MockServer mockServer;
                        
                         public MockServerInvocationHandler(MockServer mockServer)
                         {
                         this.mockServer = mockServer;
                         }
                        
                         /**
                         * @see org.jboss.remoting.ServerInvocationHandler#addListener(org.jboss.remoting.callback.InvokerCallbackHandler)
                         */
                         public void addListener(InvokerCallbackHandler callbackHandler)
                         {
                         // no asynchronous support required as of now. Implement later if required
                        
                         }
                        
                         /**
                         * On receiving a {@link MockServerRequest} the invocation handler will
                         * carry out appropriate operation on the {@link MockServer} <br>
                         *
                         * Supported requests are <br/>
                         * <li>
                         * <ul>
                         * {@link MockServerRequest.START} - On receiving this request, the invocation
                         * handler will start the {@link MockServer}
                         * </ul>
                         * <ul>
                         * {@link MockServerRequest.STOP} - On receiving this request, the invocation
                         * handler will stop the {@link MockServer}
                         * </ul>
                         * </li>
                         * @throws {@link IllegalArgumentException} If the <code>invocationRequest</code>
                         * is not supported
                         * @see org.jboss.remoting.ServerInvocationHandler#invoke(org.jboss.remoting.InvocationRequest)
                         */
                         public Object invoke(InvocationRequest invocationRequest) throws Throwable
                         {
                        
                         if (!(invocationRequest.getParameter() instanceof MockServerRequest))
                         {
                         throw new IllegalArgumentException("Unrecognized request type " + invocationRequest.getParameter());
                         }
                         MockServerRequest request = (MockServerRequest) invocationRequest.getParameter();
                         logger.info("Received request: " + request);
                        
                         // The same invocation handler can be called by multiple threads.
                         synchronized (this.mockServer)
                         {
                         if (request.equals(MockServerRequest.START))
                         {
                         this.mockServer.start();
                         }
                         else if (request.equals(MockServerRequest.STOP))
                         {
                         this.mockServer.stop();
                         }
                         else
                         {
                         throw new IllegalArgumentException("Unrecognized request " + invocationRequest.getParameter());
                         }
                         }
                        
                         logger.debug("Server in " + mockServer.getStatus() + " state");
                         return mockServer.getStatus();
                         }
                        
                         /**
                         * @see org.jboss.remoting.ServerInvocationHandler#removeListener(org.jboss.remoting.callback.InvokerCallbackHandler)
                         */
                         public void removeListener(InvokerCallbackHandler callbackHandler)
                         {
                         // do nothing - Implement later if needed
                        
                         }
                        
                         /**
                         * @see org.jboss.remoting.ServerInvocationHandler#setInvoker(org.jboss.remoting.ServerInvoker)
                         */
                         public void setInvoker(ServerInvoker invoker)
                         {
                         // do nothing - Implement later if needed
                        
                         }
                        
                         /**
                         * @see org.jboss.remoting.ServerInvocationHandler#setMBeanServer(javax.management.MBeanServer)
                         */
                         public void setMBeanServer(MBeanServer server)
                         {
                         // do nothing - Implement later if needed
                        
                         }
                        
                        }
                        



                        • 9. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                          jaikiran pai Master

                           

                          "wolfc" wrote:

                          Use NIO or Remoting 3 here.


                          Carlo,

                          I started using 2.x version of Remoting in the changes that i posted today. I will migrate to 3.0 Beta1 once it becomes available in Maven repo http://www.jboss.com/index.html?module=bb&op=viewtopic&t=145671.

                          Andrew,

                          You mentioned that you wanted the changes to be such that there can be multiple MockServer running. The changes i posted today do facilitate this. Each MockServer runs in its own JVM. Did you want those n MockServer to be in one single remote JVM or is this current behaviour OK?

                          • 10. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                            Andrew Rubinger Master

                             

                            "jaikiran" wrote:
                            Each MockServer runs in its own JVM. Did you want those n MockServer to be in one single remote JVM or is this current behaviour OK?


                            Sorry about the delay in response.

                            Server per JVM is good, and your latest patches look like they can do the trick for us. Will be glad to get this one closed out.

                            FYI, easier to review patches attached to JIRAs as opposed to long code blocks. But that might just be a personal preference of mine. ;)

                            S,
                            ALR

                            • 11. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                              jaikiran pai Master

                               

                              "ALRubinger" wrote:


                              Sorry about the delay in response.

                              No problem :)

                              "ALRubinger" wrote:

                              Server per JVM is good, and your latest patches look like they can do the trick for us. Will be glad to get this one closed out.


                              I'll get this in SVN this weekend.

                              "ALRubinger" wrote:

                              FYI, easier to review patches attached to JIRAs as opposed to long code blocks. But that might just be a personal preference of mine. ;)

                              Sure, i'll attach the patch next time for any other tasks :)

                              S,
                              ALR

                              • 12. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                                jaikiran pai Master

                                Andrew, the changes have been committed. SVN Revision 81462.

                                The issue is assigned to you so i haven't marked it resolved :)

                                • 13. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                                  Andrew Rubinger Master

                                  I'm seeing failures w/:

                                  org.jboss.remoting.CannotConnectException: Can not get connection to server. Problem establishing socket connection for InvokerLocator [socket://localhost:12345/]


                                  http://jboss.hudson.alrubinger.com/job/EJB3_Aggregator/org.jboss.ejb3$jboss-ejb3-proxy/lastBuild/testReport/

                                  ...which makes r81462 eligible for rollback. Congratulations on your first build breakage!

                                  "jaikiran" wrote:
                                  The issue is assigned to you so i haven't marked it resolved :)


                                  Ah, this is a leftover from before you had the appropriate permissions in JIRA. I've sent it over to you.

                                  S,
                                  ALR

                                  • 14. Re: EJBTHREE-1396 MockServer must report startup / shutdown
                                    jaikiran pai Master

                                    Is there some place where i can reproduce this? Locally this is working fine on my setup. Let me see the Hudson logs.

                                    1 2 Previous Next