public void exitProcess() { if (classLoader != null) { // Just to get rid of the warning.... classLoader.getClass(); } // Send a request to shutdown the spawned process and return... classLoader = null; }
public void spawnProcess() throws IOException, InterruptedException { log.debug("INSIDE spawnProcess"); // Setup the classloader and determine the port used to process the incoming requests. // TODO: make the java command configurable. String javaHome = System.getProperty("java.home"); String javaExe = javaHome + File.separator + "bin" + File.separator + "java"; int port = -1; String hostname = null; ClassLoader parent = Thread.currentThread().getContextClassLoader(); parent = (ClassLoader.getSystemClassLoader() == parent) ? null : parent; if (parent != null) { server = new ServerSocket(0); port = server.getLocalPort(); hostname = InetAddress.getLocalHost().getHostName(); classLoader = new SpawnerClassLoader(server, parent, identifier); classLoader.start(); } List<String> command = new LinkedList<String>(); command.add(javaExe); command.addAll(jvmArgs); command.add("-cp"); command.add(System.getProperty("java.class.path") + File.pathSeparator + spawnedClassPath); command.add(Spawned.class.getName()); // Create a remote class loader only if the current thread has a context class loader set. if (parent != null) { command.add(Options.PORT); command.add(String.valueOf(port)); command.add(Options.HOST); command.add(hostname); } else { command.add(Options.NOCLASSLOADER); } command.add(Options.CLASSNAME); command.add(className); if (methodName != null) { command.add(Options.METHODNAME); command.add(methodName); } // Store the system properties to a file that will be loaded by the spawned application. Properties props = System.getProperties(); File file = File.createTempFile("spawned", ".properties"); Writer out = new FileWriter(file); props.store(out, "Spawned properties"); out.close(); command.add(Options.PROPERTYFILE); command.add(file.getAbsolutePath()); log.info("command: {}", command); ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder = processBuilder.redirectErrorStream(true); process = processBuilder.start(); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); new Thread( new Runnable() { private BufferedReader input; Runnable setInput(BufferedReader input) { this.input = input; return this; } public void run() { log.debug("Inside run"); String line; try { while ((line = input.readLine()) != null) { log.info("stdout: {}", line); } } catch (IOException e) { log.debug("An exception was raised while trying to read the next line", e); } } }.setInput(input)) { { setName(Spawner.this.identifier + getName()); start(); } }; new Thread() { private File file; public void run() { try { int result = process.waitFor(); log.info("Exiting process with: {}", result); } catch (InterruptedException e) { log.error("An exception was generated when waiting for process to exit", e); } finally { Spawner.this.processExited = true; if (file.exists()) { file.delete(); } } } public void setFile(File file) { this.file = file; setName(Spawner.this.identifier + getName()); start(); } }.setFile(file); }