[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 609
  • Last Modified:

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?
0
Uncle_J
Asked:
Uncle_J
  • 4
  • 3
  • 2
  • +2
4 Solutions
 
objectsCommented:
call:

System.exit(returnCode);
0
 
CPColinSenior Java ArchitectCommented:
Calling System.exit() will exit the VM altogether.

You'll probably have to do call a different method than main(), if you can. Preferably one that *does* return a value, so you can check it for success. If no such method exists, you might be out of luck.
0
 
cmalakarCommented:
If you are executing the main() from your other class.. and the main() returns using System.exit( ), then whole JVM exits.
You invoker class does not gets any control.

If the main( ) method throws any Runtime exception, then Can catch them.. and know that there was some problem.

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
VenabiliCommented:
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.
0
 
Uncle_JAuthor Commented:
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.
0
 
VenabiliCommented:
How do you start the second program exactly? Through Process? Or in another way? And do you know how the second program specifies that there is an error? (some programs will write to stderr even on success for logging information... so you need to find out how the second program signals that  there had been an issue)
0
 
Uncle_JAuthor Commented:
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

0
 
objectsCommented:
you cannot get a return code in that case, all you know is when the main method has completed
0
 
Uncle_JAuthor Commented:
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

0
 
Uncle_JAuthor Commented:
I just divvied up the point for participating
0
 
VenabiliCommented:
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.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now