That zip helped tremendously.  Thank you.

Ok, so I have a few approaches for you. I definitely feel inspired to add some improvements to the client code, but there are ways to get around the issue with the existing code.

The underlying issue is that the client doesn't get the information that the socket has closed, because the OS is not aggressively closing the socket. It happily lets us write the entire request on that second "list" using the original socket to 127.0.0.1:4201 and doesn't say anything till we try and read the response. From our end we have no idea when the server went away: did it die before the request, did it die while reading the request, or did it die after reading it and has already executed it but died writing the response, is the server still alive and our connection went bad? It's a bit like talking to your friend on the phone and their cell phone drops or your cell phone drops, only you don't know it and keep talking to them.

In our case we are the ones killing the server so we can take aggressive action to get a new connection. Here are a few workarounds:


1. Forcefully flush the pool:   http://gist.github.com/168083

In this approach we reduce our client connection pool to 1 and then use an internal call to evict it from the pool. The result is you are guaranteed to get a new connection when you want one.

2. Use the multicast failover/retry: http://gist.github.com/168106

Here we edit the conf/multicast.properties file and set 'disabled' to false so the mutlicast support starts up. The code then uses the multicast URI to connect to the server. We also set a system property "openejb.client.requestretry" to "true". The result is that the client will listen for a server on the multicast channel when you try and connect (will wait for the configured timeout). If/When a server shows up it will send the request to it. If at any time the server disappears, the "requestretry" property will cause the client to go back to multicast listening. The new server is discovered and the request goes to it.

3. Deploy/undeploy to the same server

That said, if the ultimate goal is to write some tooling to help you deploy/undeploy apps, there is a real "powerhouse" way to do it. This is what I'd do: http://gist.github.com/168121

In that scenario we use the Deployer EJB to deploy and undeploy applications as well as get metadata about existing applications. The command line deploy/undeploy commands actually use this EJB under the covers. This way there is no need to restart the server and no need for Thread.sleep statements. The deploy method will block till the app is fully deployed and ready to be executed, the undeploy command will block until the app is fully undeployed. It does expose you to the internal AppInfo metadata which is tweaked once in a while, but is a pretty stable object tree overall. Certainly you could write some heavy duty tooling with that information.


Hope this helps!

If you get the urge to blog about it, we're happy to point to it in our blog.


-David



On Aug 1, 2009, at 3:51 PM, Keulkeul wrote:


Hi David,

Sorry for the delay, holidays ...

I have uploaded a zip file which contains
- the logs according to your exigences.
- a tiny Maven project to underline this problem.

Thanks a lot.

http://www.nabble.com/file/p24773377/standaloneopenejb.zip
standaloneopenejb.zip

Mickael


David Blevins wrote:


On Jul 28, 2009, at 2:00 PM, Keulkeul wrote:




David Blevins wrote:


On Jul 24, 2009, at 5:24 AM, Keulkeul wrote:


Hi,

I'm starting an OPENEJB Server from a Java application thanks to
RemoteServer class (located into the org.apache.openejb.config
package). In
fact, RemoteServer is a kind of wrapper which made a
Runtime.getRuntime().exec(args) with openejb-core.jar file to
execute
OPENEJB Server.

Below, the code to start server

System.setProperty("openejb.home", "D:/OSGi/openejb-3.1.1");
String[] param = new String[1];
param[0] = "start";
RemoteServer.main(param);

I can list the EJB sessions available from the current Context like
this:

Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.RemoteInitialContextFactory");
props.put(Context.PROVIDER_URL, "httpejbd://127.0.0.1:4204");
Context ctx = new InitialContext(props);
NamingEnumeration<NameClassPair> list = ctx.list("");
while (list.hasMore()) {
        System.out.println("name: " + list.next().getName());
}

Also, i can stop the current OPENEJB Server like this

param = new String[1];
param[0] = "stop";
RemoteServer.main(param);

So, i can restart a new OPENEJB Server according to the same
configuration.

param = new String[1];
param[0] = "start";
RemoteServer.main(param);

But, now when i would like to list the EJB sessions (see previous
code) from
the new instance of OPENEJB Server, i have a RuntimeException
exception
which is throwned (java.lang.RuntimeException: Invalid response from
server
:-1).

In fact, when a restart an OPENEJB Server in a same instance of
JVM it
does'nt working.

I have checked this new OPENEJB Server with a new Java program (so a
new
instance of JVM) and it is working.

It is important to note that i need to start an OpenEJB Server like
this
because i need to deploy and undeploy EJBs. These EJBs are not
located into
the same applications.

Any idea about this issue ?

Hi Mickael,

Couple questions, are you starting/stoping a standalone OpenEJB
server
or Tomcat+OpenEJB.  It seems from the start command you are
starting a
plain OpenEJB server, but the httpejbd seems to indicate you are
running a Tomcat+OpenEJB install.

The interesting thing is that in 3.1.1 you should get an "Unsupported ConnectionFactory URI scheme "httpejbd"." exception with a URL like that. Do you by chance have an old version of OpenEJB in the client
classpath?

-David




Hi David,

Thanks for your replying.

While i was writing this post i made a big mistake. It's not
"httpejb" but
"ejbd". I'm sorry. But the problem is the same. I was testing
different
solutions and it was a bad copy and paste ;-)

So i'm starting a standalone OpenEJB server not Tomcat + OpenEJB. All
OpenEJB server features are working during the first starting. But
if i'm
starting a new instance server (of course the previous server
instance is
turn off) it doesn't working.

Hmm. That's strange client behavior.  I've done a lot of testing of
the failover logic which includes being able to reconnect to a server
after its been shutdown/restarted (or crashes), so I know this
scenario works.

Is it possible you could post the full client side stack trace? Also,
can you set the "log4j.category.OpenEJB.server" log category to
"DEBUG" and send the server log output?

-David




--
View this message in context: 
http://www.nabble.com/Starting-OpenEJB-server-from-a-java-code.-tp24643630p24773377.html
Sent from the OpenEJB User mailing list archive at Nabble.com.



Reply via email to