[Design of POJO Server] - Re: JBAS-6104; slow Seam deployments
by jbalunas@redhat.com
Here is what I'm seeing related to this while attempting to test AS 5 + new JSF + seam. This is with the latest code as of about an hour ago.
When I deploy the seam app the console only shows "Welcome to Seam 2.1.1-SNAPSHOT", and the debug log shows what is below.
| 2008-11-05 09:40:14,212 DEBUG [org.ajax4jsf.resource.InternetResourceBuilder] (HDScanner) Return instance of internet resource builder org.ajax4jsf.resource.ResourceBuilderImpl@164cb82
| 2008-11-05 09:40:14,212 DEBUG [org.ajax4jsf.resource.InternetResourceBuilder] (HDScanner) Return instance of internet resource builder org.ajax4jsf.resource.ResourceBuilderImpl@164cb82
| 2008-11-05 09:40:14,270 INFO [javax.servlet.ServletContextListener] (HDScanner) Welcome to Seam 2.1.1-SNAPSHOT
| 2008-11-05 09:40:14,427 DEBUG [org.jboss.seam.deployment.DeploymentStrategy] (HDScanner) Adding org.jboss.seam.bpm.PageflowDeploymentHandler as a deployment handler
| 2008-11-05 09:40:14,576 DEBUG [org.jboss.seam.deployment.DeploymentStrategy] (HDScanner) Using org.jboss.seam.integration.jbossas.vfs.VFSScanner@1d81f33
|
At this point the application deploy hangs, and my system memory starts to rise. Something is hung up pretty good because the only way to stop the server is to kill the process.
-Jay
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4187018#4187018
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4187018
17 years, 5 months
[Design of EJB 3.0] - Re: EJBTHREE-1396 MockServer must report startup / shutdown
by jaikiran
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("\"");
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4187002#4187002
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4187002
17 years, 5 months
[Design of EJB 3.0] - EJBTHREE-1396 MockServer must report startup / shutdown
by jaikiran
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.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4187001#4187001
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4187001
17 years, 5 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: XA resource and setting the timeout
by timfox
"jhalliday" wrote : > You're saying we should only timeout unprepared txs? If so, why?
|
| Let's go back to my quote from the XA spec:
|
| "An RM can mark a transaction branch as rollback-only any time except after a successful prepare. ...An RM can also unilaterally roll back and forget a branch any time except after a successful prepare."
|
| Timeouts allow an RM to walk away from an unprepared tx that it thinks may have been abandoned. It's useful to cover e.g. client crashes. It does not lead to an inconsistent tx outcome since the tx is presumed abort at that stage anyhow.
|
| Unilaterally deciding to rollback a prepared branch is a much bigger deal as it can lead to heuristics. It can be done, but needs a lot more thought and logging.
|
OK that makes life simpler - no need to store any create time, and in the scan we only consider non prepared txs
anonymous wrote :
| Personally I'd avoid automating post-prepare rollbacks and instead provide a tool that admins can use to manually force a tx outcome. Since it may lead to data inconsistency it's not a decision to be made lightly and the best course of action usually needs some understanding of the business context e.g. in some cases it's better to stay blocked for consistency, whilst in others availability concerns may make a rollback+manual data reconciliation a more attractive option.
|
We can add this to our management interface
Thx
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4186976#4186976
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4186976
17 years, 5 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: XA resource and setting the timeout
by jhalliday
> You're saying we should only timeout unprepared txs? If so, why?
Let's go back to my quote from the XA spec:
"An RM can mark a transaction branch as rollback-only any time except after a successful prepare. ...An RM can also unilaterally roll back and forget a branch any time except after a successful prepare."
Timeouts allow an RM to walk away from an unprepared tx that it thinks may have been abandoned. It's useful to cover e.g. client crashes. It does not lead to an inconsistent tx outcome since the tx is presumed abort at that stage anyhow.
Unilaterally deciding to rollback a prepared branch is a much bigger deal as it can lead to heuristics. It can be done, but needs a lot more thought and logging.
Personally I'd avoid automating post-prepare rollbacks and instead provide a tool that admins can use to manually force a tx outcome. Since it may lead to data inconsistency it's not a decision to me made lightly and the best course of action usually needs some understanding of the business context e.g. in some cases it's better to stay blocked for consistency, whilst in others availability concerns may make a rollback+manual data reconciliation a more attractive option.
> No, we just include prepared txs
ok, that's fine. Some systems will include the unprepared ones too, on the basis that the tx manager will rollback any it does not recognise, which means they get cleaned up sooner than a timeout may achieve. It's not a common approach though.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4186974#4186974
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4186974
17 years, 5 months