Friday, 15 February 2013

Attempting to Fork a java process and connect rmi as client but forked process is exiting -



Attempting to Fork a java process and connect rmi as client but forked process is exiting -

** see updates first original implemenation contains false assumptions backstory

i have problem must fork processes, reason using jni , single threaded r process. need way monitor memory , cpu, forking seems real solution. cannot implement have more 1 r invocation per process, have definitly tried around limitation pretty sure not possible due rinside setup method.

current implementation

i trying fork process , connect rmi connection , store these in stacked pool. problem registry.bind() method not blocking should. when binding registry in main process process block , wait remote method calls when starting runtime.getruntime().exec() process not block , exits. causes endpoint daemon close , receive socket errors when trying communicate daemon. using gfork library fork process ability receive exceptions , such on startup of forked process.

public class jridaemon implements iroperationremoteprovider, serializable, runnable { /** * serialization id */ private static final long serialversionuid = 2279972098306474322l; /** * daemon logger */ private static final logger logger = logger.getlogger(jridaemon.class.getname()); /** * exeuctor service used execute our job, alternative * newsinglethreadexecutor of import because r single threaded , jri * puts check in , kill if thread manipulated. */ private static executorservice executorservice = executors.newsinglethreadexecutor(); /** * implemenation uses exeuctor service run analytics * operation. executor service used because r single threaded , * cannot called outside. */ private jriexecutiontask callableoperation; /** * unique id can fetch daemon. */ private final string daemonid; private jridaemon() { this(uuid.randomuuid().tostring()); } private jridaemon(string daemonid) { this.daemonid = daemonid; } private string getdaemonid() { homecoming daemonid; } @override public void run() { logger.info("starting jri daemon"); system.out.println("starting jri daemon"); seek { iroperationremoteprovider stub = (iroperationremoteprovider) unicastremoteobject.exportobject(this, 0); registry registry = locateregistry.getregistry(); registry.rebind(daemonid, stub); } grab (exception e) { e.printstacktrace(); throw new runtimeexception("exception occurred when initializing rmi agent ", e); } system.out.println("daemon done"); logger.fine("exiting jridaemon#run"); } /** * close connection r services. * @throws notboundexception * @throws remoteexception * @throws accessexception */ public void close() throws exception { logger.info("calling close !!!!!!!!!"); //if (registry != null) { // registry.unbind(daemonid); //} //system.exit(0); } /** * @see iroperationprovider#execute(ianalyticsoperation, list, list) */ @override public map<string, imetric> execute(ianalyticsoperation operation, list<ianalyticsoperationinput> inputs, list<? extends idataprovider> dataprovider) throws exception { callableoperation = new jriexecutiontask(inputs, operation, dataprovider); future<map<string, imetric>> execution = executorservice.submit((callable<map<string, imetric>>) callableoperation); homecoming execution.get(); } /** * @see iroperationprovider#interrupt() * * todo come solution on stopping , restarting thread in * rengine implementation. */ @override public void interrupt() { system.out.println("calling interrupt on executor service"); executorservice.shutdown(); // can't yet because causes segfault in task engine // process. // callableoperation.interrupt(); } @override public boolean isallgood() { homecoming true; } @override public void activate() { } @override public void passivate() { } /** * here testing purposes. * @param args * @throws exception */ public static void main(string args[] ) throws exception { iroperationremoteprovider provider = create(); thread.sleep(10000); system.out.println(" " + provider.isallgood()); } /** * creates daemon , initializes returns client can used * talk server. daemon useless calling process * separate process , utilize client communicate * jri daemon process. * * @return */ public static iroperationremoteprovider create() throws exception { locateregistry.createregistry(1099); string daemonid = uuid.randomuuid().tostring(); jridaemon daemon = new jridaemon(daemonid); fork<jridaemon, org.gfork.types.void> forkeddaemon = new fork<jridaemon, org.gfork.types.void>(daemon); //forkeddaemon.setjvmoptions("-djava.security.manager -djava.security.policy=\"taskenginesecurity.policy\""); logger.info("calling run task"); forkeddaemon.addlistener(new listener<jridaemon, org.gfork.types.void>() { @override public void onfinish(fork<jridaemon, void> fork, boolean waskilled) throws illegalaccessexception, interruptedexception { logger.info("task finished exit value -> " + fork.getexitvalue() + " killed ->" + waskilled); } @override public void onerror(fork<jridaemon, void> fork) throws illegalaccessexception, interruptedexception { logger.info("error " + fork.getstderr()); } @override public void onexception(fork<jridaemon, void> fork) throws illegalaccessexception, interruptedexception, ioexception, classnotfoundexception { logger.log(level.severe, " erorro occurred in daemon ", fork.getexception()); } }); fork.setloggingenabled(true); forkeddaemon.execute(); forkeddaemon.waitfor(); logger.info("standard out " + forkeddaemon.getstdout()); if (forkeddaemon.isexception()) { throw new runtimeexception("unble create remote provider ", forkeddaemon.getexception()); } //thread.sleep(2000); registry registry = locateregistry.getregistry(); iroperationremoteprovider process = (iroperationremoteprovider) registry.lookup(daemonid); homecoming process; } }

i utilize create method create new implementation of analytics provider, fork class calls run when executes spawn new daemon. if set exact same code in public static void main(string[] args) process daemonizes , waits rmi calls, when exeting through operation not.

here gfrork execute method , can see uses runtime.exec

/** * starts new java process runs task. * subprocess inherits environment including class path * scheme properties of current process. jvm launched using * executable derived standard scheme property 'java.home'. * <p> * standard output (system.out) of task can reddish {@link #getstdout()} or * forwarded file, see {@link #setstdoutwriter(writer)}. * same possible standard error (system.err), * see {@link #getstderr()} , {@link #setstderrwriter(writer)}. * * @throws exception */ public synchronized void execute() throws exception { if (isexecuting()) { throw new illegalstateexception(fork_is_already_executing); } exec = runtime.getruntime().exec(createcmdarray(), null, workingdir); taskstdoutreader = new bufferedreader(new inputstreamreader(exec.getinputstream())); taskerrorreader = new bufferedreader(new inputstreamreader(exec.geterrorstream())); readerror(); readstdout(); waitforfinishedthread = new thread("jforkwaitforfinishedthread") { // needed notify listeners after execution @override public void run() { seek { waitfor(); } grab (final exception e) { e.printstacktrace(); stderrtext.append(string.format("error jforklistenernotifier: %s%n", e.tostring())); } } }; waitforfinishedthread.start(); }

i have added sleep timers watch process , start , shortly after exits no errors , 0 status. have verified if there problem configuring rmi in run method homecoming exception. rmi seems initializing correctly not block forked process not exit. have rtfm on runtime.exec , have not thought causing exit. help appreciated.

update

thank ejp though remarks condescending correct. made wrong assumption bind blocking due fact process did not die rather creates separate thread handle rmi communication. keeps process alive.

import java.rmi.remote; import java.rmi.remoteexception; import java.rmi.registry.locateregistry; import java.rmi.registry.registry; import java.rmi.server.unicastremoteobject; public class runnablermidaemon implements remote { public static void main(string args[]) throws interruptedexception { string daemonid = "123"; system.out.println("starting"); registry registry; seek { runnablermidaemon daemon = new runnablermidaemon(); registry = locateregistry.getregistry(); final remote stub = (remote) unicastremoteobject.exportobject(daemon, 0); registry.rebind(daemonid, stub); thread.sleep(1000); } grab (remoteexception e) { throw new runtimeexception("remote exception occurred while running " + e); } system.out.println("ending"); } } import java.io.ioexception; public class forkrmidaemon { public static void main(string args[]) throws ioexception, interruptedexception { system.out.println("starting fork"); runtime.getruntime().exec("java -cp . runnablermidaemon"); thread.sleep(10000); system.out.println("completed fork"); } }

when first process dies runtime.getruntime().exec() process still alive.

thanatos:testingrmifork chris$ java forkrmidaemon starting fork completed fork tv-mini:testingrmifork chris$ ps -ef | grep java 501 25499 1 0 0:00.10 ttys007 0:00.72 /usr/bin/java -cp . runnablermidaemon 501 25501 25413 0 0:00.00 ttys007 0:00.00 grep java thanatos:testingrmifork chris$

my investigation not finish yet appears the simple gfork library doing close process on return. have looked through gfork code have not seen can happening.

thanks ejp , applogize of wrong information. guessing gfork doing trickery because allows phone call method not main.

i assumed java treated threads more c pthreads , have had create while loop in main() otherwise threads killed when main exits. mistake

the problem registry.bind() method not blocking should. when binding registry in main process process block , wait remote method calls.

no won't. fantasy. made up. there nil in documentation says of sort. not blocking phone call (except moments during communicating registry); , not 'block , wait remote method calls'. returns code. mustn't surprised if create behaviour , scheme doesn't exhibit it.

this causes endpoint daemon close

no doesn't. endpoint daemon causes close, somehow. rmi starts non-daemon threads handle incoming connections, jvm has exported remote objects won't exit until remote objects unexported, either explicitly or via gc, or application calls system.exit(). way prevent gc of remote objects store static references them.

i must don't understand why exec-ing sub-process, if going in main process wait it.

java rmi

No comments:

Post a Comment