Last active
September 23, 2017 16:11
-
-
Save krmahadevan/4649471 to your computer and use it in GitHub Desktop.
This is a standalone java application that can continuously monitor a another JVM and if the JVM crashes or exits it can re-spawn it again.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.IOException; | |
import java.util.Properties; | |
import org.apache.commons.exec.CommandLine; | |
import org.apache.commons.exec.DefaultExecuteResultHandler; | |
import org.apache.commons.exec.DefaultExecutor; | |
import org.apache.commons.exec.ExecuteException; | |
import org.apache.commons.exec.PumpStreamHandler; | |
import org.apache.commons.exec.ShutdownHookProcessDestroyer; | |
/** | |
* This is a standalone class that essentially helps spawn a jar given via the commandline along with the | |
* arguments that are required by the jar. | |
* | |
*/ | |
public class JarSpawner { | |
/** | |
* This class is internally used to save the absolute file path of a given jar and its command line arguments. | |
* | |
*/ | |
static class JarFileAttributes { | |
public File getFilePath() { | |
return filePath; | |
} | |
public String getJarArgs() { | |
return jarArgs; | |
} | |
@Override | |
public String toString() { | |
return "JarFileAttributes [filePath=" + filePath.getAbsolutePath() + ", jarArgs=" + jarArgs + "]"; | |
} | |
private File filePath; | |
private String jarArgs; | |
public JarFileAttributes(File filePath, String jarArgs) { | |
this.filePath = filePath; | |
this.jarArgs = jarArgs; | |
} | |
} | |
public static void main(String[] args) throws ExecuteException, IOException, InterruptedException { | |
JarFileAttributes attributes = getJarFile(args); | |
Properties properties = new Properties(); | |
properties.load(JarSpawner.class.getResourceAsStream("/spawner.properties")); | |
long interval = Long.parseLong((String) properties.get("defaultInterval")); | |
while (true) { | |
continuouslyRestart(attributes, interval); | |
Thread.sleep(interval); | |
System.out.println("Application exited. Respawning the application again"); | |
} | |
} | |
/** | |
* This method parses the commandline argument and extracts the jar file and its arguments. | |
* @param args - The command line arguments that needs to be parsed. | |
* @return - A {@link JarFileAttributes} object that represents the path of the jar file and its command line args. | |
*/ | |
public static JarFileAttributes getJarFile(String[] args) { | |
File file = null; | |
boolean wasJarFound = false; | |
int jarArgsIndex = 0; | |
StringBuffer sb = new StringBuffer(); | |
for (int i = 0; i < args.length; i++) { | |
if (args[i].contains(".jar")) { | |
file = new File(args[i]); | |
wasJarFound = true; | |
jarArgsIndex = i + 1; | |
} | |
} | |
if (!wasJarFound) { | |
throw new RuntimeException("Please specify the jar file"); | |
} | |
for (int i = jarArgsIndex; i < args.length; i++) { | |
sb.append(args[i]).append(" "); | |
} | |
return new JarFileAttributes(file, sb.toString()); | |
} | |
/** | |
* This method spawns a jar, and waits for it to exit [either cleanly or forcibly] | |
* | |
* @param attributes - {@link JarFileAttributes} that represents the jar file path and its arguments. | |
* @param interval - How often should the application check if the jar is still running or if it exit. | |
* @throws ExecuteException | |
* @throws IOException | |
* @throws InterruptedException | |
*/ | |
public static void continuouslyRestart(JarFileAttributes attributes, long interval) | |
throws ExecuteException, IOException, InterruptedException { | |
System.out.println("Spawning the application "); | |
CommandLine cmdLine = new CommandLine("java"); | |
cmdLine.addArgument("-jar"); | |
cmdLine.addArguments(attributes.getFilePath().getAbsolutePath() + " " + attributes.getJarArgs()); | |
DefaultExecutor executor = new DefaultExecutor(); | |
executor.setStreamHandler(new PumpStreamHandler()); | |
executor.setProcessDestroyer(new ShutdownHookProcessDestroyer()); | |
DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); | |
executor.execute(cmdLine, handler); | |
while (!handler.hasResult()) { | |
Thread.sleep(interval); | |
} | |
if (handler.hasResult()) { | |
ExecuteException e = handler.getException(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The properties file [spawner.properties] has just the below contents in it:
How often should the JVM spawner check to see if the client application is running or not.
By default we will check ONLY once in 10 minutes.
defaultInterval=600000