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.