Link to home
Start Free TrialLog in
Avatar of Uncle_J
Uncle_J

asked on

Get exit code from programmatic call to main()

I am calling the main() function of another class from within one of my classes and need to know if the call was successful. Since main() is a void function and does not throw an exception, how can I know if the execution was successful?
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you cannot use another method as already mentioned above, you can try to print something into the System.out or System.err from the second program and read it from the first. Or use a file/DB for example...

The way I do these most of the cases is with a small file - if the file is there after the code exits, something wrong had happened and the file contains the data for it. So you read and remove the file from the first one and act accordingly. If the program is multithreaded, make sure you differenciate the different files (passing the file name to the second program is probably the easiest way). And it will really depend on what you do in the programs - if you have a DB of any type, it can also be used.
Avatar of Uncle_J
Uncle_J

ASKER

Thank you for the suggestions. Perhaps I should explain that I have no control over the code of the first program so I cannot add an exit call or add the writing to of a file or DB. The called main() function does write to standard out and standard error. Might there be a way for the calling code to listen or intercept anything being written to stdout/stderr? Perhaps if it can tell if anything was written to stderr it considers the call a fail.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Uncle_J

ASKER

Lets name the called class 'com.foo.ExecutedClass' and the calling class 'com.bar.CallingClass'. ExecutedClass can be run as a Java program as it has a main() function. It writes messages to stdout and any errors to stderr. It does not log to any file. I really dont care about capturing any messages generated by the class. I am only interested if executed successfully. Here is a sudo example of how I am calling the main

package com.bar

import com.foo.ExecutedClass;

public class CallingClass {

public void execute() {
  String[] args = new String[2];
  args[0] = "-a";
  args[1] = "Example parameter value";
  ExecutedClass.main(args);
}
}

Open in new window

you cannot get a return code in that case, all you know is when the main method has completed
Avatar of Uncle_J

ASKER

It looks like executed class does call System.exit() which is killing the VM. I did not notice because I was only executing it once and really did not have any code to run after the call. Now that I have the call in a loop I noticed that the program completes after the first iteration.

Here is my "solution":
Create a anonymous instance of the SecurityManager class and implement my own checkPermission() function that gets called with a RuntimePermission parameter when an attempt is made to exit the VM via System.exit(). The permission name starts with "exitVM" followed by the exit code. I can use this to determine if the program has completed successfully... See my code example.

//Define new Exception type
private class BlockedExitException extends SecurityException {
	private int exitCode_;
	
	public BlockedExitException(String message, int exitCode) {
		super(message);
		exitCode_ = exitCode;
	}
	public int getExitCode() {
		return exitCode_;
	}
}


//Somewhere in the calling code .....

SecurityManager securityManager = new SecurityManager() {
	public void checkPermission(Permission permission) {
		if (permission instanceof RuntimePermission
				&& permission.getName().startsWith("exitVM")) {
			String exitCode = permission.getName().split("\\.")[1];
			throw new BlockedExitException("System.exit blocked", Integer.valueOf(exitCode));
		}
	}
};
System.setSecurityManager(securityManager);


//When calling the main class....
try {
	ExecutedClass.main(args);
} catch (BlockedExitException ex) {
	if (ex.getExitCode() > 0) {
		//Failed
	}else{
                //passed
        }
}
 

Open in new window

Avatar of Uncle_J

ASKER

I just divvied up the point for participating
Yep - if the second program calls exit, you are pretty much stuck with this.

Or alternatively you can force the start of a second JVM for the second program so when it exits, it kills only its own JVM and leaves the first one in tact.

Anyway - good that you have a solution.