mirror of
https://github.com/openjdk/jdk8u.git
synced 2025-12-15 14:22:57 -06:00
8028474: sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh timeout, leaves looping process
Reviewed-by: sla, jbachorik, rriggs
This commit is contained in:
parent
03c0001c0a
commit
e2c02255a2
@ -251,9 +251,6 @@ sun/security/tools/keytool/standard.sh solaris-all
|
||||
|
||||
# jdk_tools
|
||||
|
||||
# 8028474
|
||||
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh generic-all
|
||||
|
||||
# Tests take too long, on sparcs see 7143279
|
||||
tools/pack200/CommandLineTests.java solaris-all, macosx-all
|
||||
tools/pack200/Pack200Test.java solaris-all, macosx-all
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,228 +21,299 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.regex.*;
|
||||
import java.util.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import sun.jvmstat.monitor.*;
|
||||
import sun.jvmstat.monitor.event.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class MonitorVmStartTerminate {
|
||||
import jdk.testlibrary.OutputBuffer;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
import sun.jvmstat.monitor.MonitoredHost;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.MonitoredVmUtil;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
import sun.jvmstat.monitor.event.HostEvent;
|
||||
import sun.jvmstat.monitor.event.HostListener;
|
||||
import sun.jvmstat.monitor.event.VmStatusChangeEvent;
|
||||
|
||||
private static final int SLEEPERS = 10;
|
||||
private static final int SLEEPTIME = 5000; // sleep time for a sleeper
|
||||
private static final int EXECINTERVAL = 3000; // wait time between exec's
|
||||
/*
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
Test starts ten Java processes, each with a unique id.
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
Each process creates a file named after the id and then it waits for
|
||||
the test to remove the file, at which the Java process exits.
|
||||
|
||||
String sleeperArgs = SLEEPTIME + " " + now;
|
||||
String sleeperPattern = "Sleeper " + sleeperArgs + " \\d+$";
|
||||
The processes are monitored by the test to make sure notifications
|
||||
are sent when they are started/terminated.
|
||||
|
||||
To avoid Java processes being left behind, in case of an unexpected
|
||||
failure, shutdown hooks are installed that remove files when the test
|
||||
exits. If files are not removed, i.e. due to a JVM crash, the Java
|
||||
processes will exit themselves after 1000 s.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4990825
|
||||
* @summary attach to external but local JVM processes
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main/othervm MonitorVmStartTerminate
|
||||
*/
|
||||
public final class MonitorVmStartTerminate {
|
||||
|
||||
private static final int PROCESS_COUNT = 10;
|
||||
private static final long PROCESS_TIMEOUT_IN_NS = 1000*1000_000_000L;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
|
||||
MonitoredHost host = MonitoredHost.getMonitoredHost("localhost");
|
||||
host.setInterval(200);
|
||||
host.setInterval(1); // 1 ms
|
||||
|
||||
Matcher matcher = Pattern.compile(sleeperPattern).matcher("");
|
||||
SleeperListener listener = new SleeperListener(host, matcher, SLEEPERS);
|
||||
String id = UUID.randomUUID().toString();
|
||||
|
||||
List<JavaProcess> javaProcesses = new ArrayList<>();
|
||||
for (int i = 0; i < PROCESS_COUNT; i++) {
|
||||
javaProcesses.add(new JavaProcess(id + "_" + i));
|
||||
}
|
||||
|
||||
Listener listener = new Listener(host, javaProcesses);
|
||||
host.addHostListener(listener);
|
||||
|
||||
SleeperStarter ss = new SleeperStarter(SLEEPERS, EXECINTERVAL,
|
||||
sleeperArgs);
|
||||
ss.start();
|
||||
|
||||
System.out.println("Waiting for "
|
||||
+ SLEEPERS + " sleepers to terminate");
|
||||
try {
|
||||
ss.join();
|
||||
} catch (InterruptedException e) {
|
||||
throw new Exception("Timed out waiting for sleepers");
|
||||
for (JavaProcess javaProcess : javaProcesses) {
|
||||
javaProcess.start();
|
||||
}
|
||||
listener.waitForSleepersToStart();
|
||||
listener.waitForSleepersToTerminate();
|
||||
|
||||
// Wait for all processes to start before terminating
|
||||
// them, so pids are not reused within a poll interval.
|
||||
System.out.println("Waiting for all processes to get started notification");
|
||||
listener.started.acquire(PROCESS_COUNT);
|
||||
|
||||
for (JavaProcess javaProcess : javaProcesses) {
|
||||
javaProcess.terminate();
|
||||
}
|
||||
System.out.println("Waiting for all processes to get terminated notification");
|
||||
listener.terminated.acquire(PROCESS_COUNT);
|
||||
|
||||
host.removeHostListener(listener);
|
||||
}
|
||||
|
||||
public static class SleeperListener implements HostListener {
|
||||
|
||||
private final List<Integer> targets = new ArrayList<>();
|
||||
private final CountDownLatch terminateLatch;
|
||||
private final CountDownLatch startLatch;
|
||||
private static final class Listener implements HostListener {
|
||||
private final Semaphore started = new Semaphore(0);
|
||||
private final Semaphore terminated = new Semaphore(0);
|
||||
private final MonitoredHost host;
|
||||
private final Matcher patternMatcher;
|
||||
private final List<JavaProcess> processes;
|
||||
|
||||
public SleeperListener(MonitoredHost host, Matcher matcher, int count) {
|
||||
public Listener(MonitoredHost host, List<JavaProcess> processes) {
|
||||
this.host = host;
|
||||
this.patternMatcher = matcher;
|
||||
this.terminateLatch = new CountDownLatch(count);
|
||||
this.startLatch = new CountDownLatch(count);
|
||||
}
|
||||
|
||||
public void waitForSleepersToTerminate() throws InterruptedException {
|
||||
terminateLatch.await();
|
||||
}
|
||||
|
||||
public void waitForSleepersToStart() throws InterruptedException {
|
||||
startLatch.await();
|
||||
}
|
||||
|
||||
private void printList(Set<Integer> list, String msg) {
|
||||
System.out.println(msg + ":");
|
||||
for (Integer lvmid : list) {
|
||||
try {
|
||||
VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
|
||||
MonitoredVm target = host.getMonitoredVm(vmid);
|
||||
|
||||
StringMonitor cmdMonitor =
|
||||
(StringMonitor)target.findByName("sun.rt.javaCommand");
|
||||
String cmd = cmdMonitor.stringValue();
|
||||
|
||||
System.out.println("\t" + lvmid.intValue() + ": "
|
||||
+ "\"" + cmd + "\"" + ": ");
|
||||
} catch (URISyntaxException e) {
|
||||
System.err.println("Unexpected URISyntaxException: "
|
||||
+ e.getMessage());
|
||||
} catch (MonitorException e) {
|
||||
System.out.println("\t" + lvmid.intValue()
|
||||
+ ": error reading monitoring data: "
|
||||
+ " target possibly terminated?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int addStarted(Set<Integer> started) {
|
||||
int found = 0;
|
||||
for (Integer lvmid : started) {
|
||||
try {
|
||||
VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
|
||||
MonitoredVm target = host.getMonitoredVm(vmid);
|
||||
|
||||
StringMonitor cmdMonitor =
|
||||
(StringMonitor)target.findByName("sun.rt.javaCommand");
|
||||
String cmd = cmdMonitor.stringValue();
|
||||
|
||||
patternMatcher.reset(cmd);
|
||||
System.out.print("Started: " + lvmid.intValue()
|
||||
+ ": " + "\"" + cmd + "\"" + ": ");
|
||||
|
||||
if (patternMatcher.matches()) {
|
||||
System.out.println("matches pattern - recorded");
|
||||
targets.add(lvmid);
|
||||
found++;
|
||||
}
|
||||
else {
|
||||
System.out.println("does not match pattern - ignored");
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
System.err.println("Unexpected URISyntaxException: "
|
||||
+ e.getMessage());
|
||||
} catch (MonitorException e) {
|
||||
System.err.println("Unexpected MonitorException: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private int removeTerminated(Set<Integer> terminated) {
|
||||
int found = 0;
|
||||
for (Integer lvmid : terminated) {
|
||||
/*
|
||||
* we don't attempt to attach to the target here as it's
|
||||
* now dead and has no jvmstat share memory file. Just see
|
||||
* if the process id is among those that we saved when we
|
||||
* started the targets (note - duplicated allowed and somewhat
|
||||
* expected on windows);
|
||||
*/
|
||||
System.out.print("Terminated: " + lvmid.intValue() + ": ");
|
||||
if (targets.contains(lvmid)) {
|
||||
System.out.println("matches pattern - termination recorded");
|
||||
targets.remove(lvmid);
|
||||
found++;
|
||||
}
|
||||
else {
|
||||
System.out.println("does not match pattern - ignored");
|
||||
}
|
||||
}
|
||||
return found;
|
||||
this.processes = processes;
|
||||
printStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void vmStatusChanged(VmStatusChangeEvent ev) {
|
||||
printList(ev.getActive(), "Active");
|
||||
printList(ev.getStarted(), "Started");
|
||||
printList(ev.getTerminated(), "Terminated");
|
||||
public void vmStatusChanged(VmStatusChangeEvent event) {
|
||||
releaseStarted(event.getStarted());
|
||||
releaseTerminated(event.getTerminated());
|
||||
printStatus();
|
||||
}
|
||||
|
||||
int recentlyStarted = addStarted(ev.getStarted());
|
||||
int recentlyTerminated = removeTerminated(ev.getTerminated());
|
||||
private void printStatus() {
|
||||
System.out.printf("started=%d, terminated=%d\n",
|
||||
started.availablePermits(), terminated.availablePermits());
|
||||
}
|
||||
|
||||
for (int i = 0; i < recentlyTerminated; i++) {
|
||||
terminateLatch.countDown();
|
||||
}
|
||||
for (int i = 0; i < recentlyStarted; i++) {
|
||||
startLatch.countDown();
|
||||
@Override
|
||||
public void disconnected(HostEvent arg0) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
private void releaseStarted(Set<Integer> ids) {
|
||||
System.out.println("realeaseStarted(" + ids + ")");
|
||||
for (Integer id : ids) {
|
||||
releaseStarted(id);
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnected(HostEvent ev) {
|
||||
private void releaseStarted(Integer id) {
|
||||
for (JavaProcess jp : processes) {
|
||||
if (hasMainArgs(id, jp.getMainArgsIdentifier())) {
|
||||
// store id for terminated identification
|
||||
jp.setId(id);
|
||||
System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
|
||||
started.release();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseTerminated(Set<Integer> ids) {
|
||||
System.out.println("releaseTerminated(" + ids + ")");
|
||||
for (Integer id : ids) {
|
||||
releaseTerminated(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseTerminated(Integer id) {
|
||||
for (JavaProcess jp : processes) {
|
||||
if (id.equals(jp.getId())) {
|
||||
System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
|
||||
terminated.release();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMainArgs(Integer id, String args) {
|
||||
try {
|
||||
VmIdentifier vmid = new VmIdentifier("//" + id.intValue());
|
||||
MonitoredVm target = host.getMonitoredVm(vmid);
|
||||
String monitoredArgs = MonitoredVmUtil.mainArgs(target);
|
||||
if (monitoredArgs != null && monitoredArgs.contains(args)) {
|
||||
return true;
|
||||
}
|
||||
} catch (URISyntaxException | MonitorException e) {
|
||||
// ok. process probably not running
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SleeperStarter extends Thread {
|
||||
public final static class JavaProcess {
|
||||
|
||||
private final JavaProcess[] processes;
|
||||
private final int execInterval;
|
||||
private final String args;
|
||||
private static final class ShutdownHook extends Thread {
|
||||
private final JavaProcess javaProcess;
|
||||
|
||||
public SleeperStarter(int sleepers, int execInterval, String args) {
|
||||
this.execInterval = execInterval;
|
||||
this.args = args;
|
||||
this.processes = new JavaProcess[sleepers];
|
||||
}
|
||||
|
||||
private synchronized int active() {
|
||||
int active = processes.length;
|
||||
for(JavaProcess jp : processes) {
|
||||
try {
|
||||
jp.exitValue();
|
||||
active--;
|
||||
} catch (IllegalThreadStateException e) {
|
||||
// process hasn't exited yet
|
||||
}
|
||||
public ShutdownHook(JavaProcess javaProcess) {
|
||||
this.javaProcess = javaProcess;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
javaProcess.terminate();
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("Starting " + processes.length + " sleepers");
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
try {
|
||||
Path path = Paths.get(args[0]);
|
||||
createFile(path);
|
||||
waitForRemoval(path);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
String[] classpath = {
|
||||
"-classpath",
|
||||
System.getProperty("java.class.path")
|
||||
};
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
for (int i = 0; i < processes.length; i++) {
|
||||
try {
|
||||
System.out.println("Starting Sleeper " + i);
|
||||
synchronized(this) {
|
||||
processes[i] = new JavaProcess("Sleeper", args + " " + i);
|
||||
processes[i].addOptions(classpath);
|
||||
}
|
||||
processes[i].start();
|
||||
Thread.sleep(execInterval);
|
||||
} catch (InterruptedException ignore) {
|
||||
} catch (IOException e) {
|
||||
System.err.println(
|
||||
"IOException trying to start Sleeper " + i + ": "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// spin waiting for the processes to terminate
|
||||
while (active() > 0) ;
|
||||
private static void createFile(Path path) throws IOException {
|
||||
Files.write(path, new byte[0], StandardOpenOption.CREATE);
|
||||
if (!Files.exists(path)) {
|
||||
throw new Error("Newly created file " + path
|
||||
+ " does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
private static void waitForRemoval(Path path) {
|
||||
long start = System.nanoTime();
|
||||
while (true) {
|
||||
long now = System.nanoTime();
|
||||
long waited = now - start;
|
||||
System.out.println("Waiting for " + path + " to be removed, " + waited + " ns");
|
||||
if (!Files.exists(path)) {
|
||||
return;
|
||||
}
|
||||
if (waited > PROCESS_TIMEOUT_IN_NS) {
|
||||
System.out.println("Start: " + start);
|
||||
System.out.println("Now: " + now);
|
||||
System.out.print("Process timed out after " + waited + " ns. Abort.");
|
||||
System.exit(1);
|
||||
}
|
||||
takeNap();
|
||||
}
|
||||
}
|
||||
|
||||
private static void takeNap() {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private final String mainArgsIdentifier;
|
||||
private final ShutdownHook shutdownHook;
|
||||
private volatile Integer id;
|
||||
|
||||
public JavaProcess(String mainArgsIdentifier) {
|
||||
this.mainArgsIdentifier = mainArgsIdentifier;
|
||||
this.shutdownHook = new ShutdownHook(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a Java process asynchronously.
|
||||
*
|
||||
* The process runs until {@link #stop()} is called. If test exits
|
||||
* unexpectedly the process will be cleaned up by a shutdown hook.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void start() throws Exception {
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
System.out.println("Starting " + getMainArgsIdentifier());
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
executeJava();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
new Thread(r).start();
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
try {
|
||||
System.out.println("Terminating " + mainArgsIdentifier);
|
||||
Files.delete(Paths.get(mainArgsIdentifier));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||
}
|
||||
|
||||
private void executeJava() throws Exception, IOException {
|
||||
String className = JavaProcess.class.getName();
|
||||
String classPath = System.getProperty("test.classes");
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-cp",
|
||||
classPath, className, mainArgsIdentifier);
|
||||
OutputBuffer ob = ProcessTools.getOutput(pb.start());
|
||||
System.out.println("Java Process " + getMainArgsIdentifier() + " stder:"
|
||||
+ ob.getStderr());
|
||||
System.err.println("Java Process " + getMainArgsIdentifier() + " stdout:"
|
||||
+ ob.getStdout());
|
||||
}
|
||||
|
||||
public String getMainArgsIdentifier() {
|
||||
return mainArgsIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
#
|
||||
# @test
|
||||
# @bug 4990825
|
||||
# @summary attach to external but local JVM processes
|
||||
# @library ../../testlibrary
|
||||
# @build Sleeper
|
||||
# @build JavaProcess
|
||||
# @build MonitorVmStartTerminate
|
||||
# @run shell MonitorVmStartTerminate.sh
|
||||
#
|
||||
|
||||
. ${TESTSRC-.}/../../testlibrary/utils.sh
|
||||
|
||||
setup
|
||||
verify_os
|
||||
|
||||
JAVA="${TESTJAVA}/bin/java"
|
||||
CP=${TESTJAVA}${FS}lib${FS}tools.jar${PS}${TESTCLASSES}${PS}${TESTCLASSES}${FS}..${FS}..${FS}testlibrary
|
||||
|
||||
${JAVA} ${TESTVMOPTS} -classpath ${CP} MonitorVmStartTerminate
|
||||
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class JavaProcess {
|
||||
|
||||
protected Process process = null;
|
||||
|
||||
private String classname;
|
||||
private StringBuilder classArgs;
|
||||
private StringBuilder javaOptions;
|
||||
|
||||
private static String java = System.getProperty("java.home")
|
||||
+ File.separator + "bin"
|
||||
+ File.separator + "java";
|
||||
|
||||
public JavaProcess(String classname) {
|
||||
this(classname, "", "");
|
||||
}
|
||||
|
||||
public JavaProcess(String classname, String classArgs) {
|
||||
this(classname, "", classArgs);
|
||||
}
|
||||
|
||||
public JavaProcess(String classname, String javaOptions, String classArgs) {
|
||||
this.classname = classname;
|
||||
this.javaOptions = new StringBuilder(javaOptions);
|
||||
this.classArgs = new StringBuilder(classArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* add java options to the java command
|
||||
*/
|
||||
public void addOptions(String[] opts) {
|
||||
if (javaOptions != null && javaOptions.length() > 0) {
|
||||
javaOptions.append(" ");
|
||||
}
|
||||
|
||||
for (int i = 0; i < opts.length; i++) {
|
||||
if (i != 0) {
|
||||
javaOptions.append(" ");
|
||||
}
|
||||
javaOptions.append(opts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add arguments to the class arguments
|
||||
*/
|
||||
public void addArguments(String[] args) {
|
||||
if (classArgs != null && classArgs.length() > 0) {
|
||||
classArgs.append(" ");
|
||||
}
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (i != 0) {
|
||||
classArgs.append(" ");
|
||||
}
|
||||
classArgs.append(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* start the java process
|
||||
*/
|
||||
public void start() throws IOException {
|
||||
if (process != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String javaCommand = java + " " + javaOptions + " "
|
||||
+ classname + " " + classArgs;
|
||||
|
||||
System.out.println("exec'ing: " + javaCommand);
|
||||
|
||||
process = Runtime.getRuntime().exec(javaCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy the java process
|
||||
*/
|
||||
public void destroy() {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
process = null;
|
||||
}
|
||||
|
||||
public int exitValue() {
|
||||
if (process != null) {
|
||||
return process.exitValue();
|
||||
}
|
||||
throw new RuntimeException("exitValue called with process == null");
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
if (process != null) {
|
||||
return process.getErrorStream();
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"getErrorStream() called with process == null");
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
if (process != null) {
|
||||
return process.getInputStream();
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"getInputStream() called with process == null");
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
if (process != null) {
|
||||
return process.getOutputStream();
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"getOutputStream() called with process == null");
|
||||
}
|
||||
|
||||
public int waitFor() throws InterruptedException {
|
||||
if (process != null) {
|
||||
return process.waitFor();
|
||||
}
|
||||
throw new RuntimeException("waitFor() called with process == null");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user