diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 47c05aaf7d87d748400f80a0500df8f83cc04123..cd0b1fdc3446ad8688f7e65f63636b9f04e823d9 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -182,9 +182,6 @@ com/sun/net/httpserver/bugs/6725892/Test.java generic-all
# Filed 7036666
com/sun/net/httpserver/Test9a.java generic-all
-# 7079145 java/net/ipv6tests/UdpTest.java hang at IPv6 only data exchange
-java/net/ipv6tests/UdpTest.java linux-all
-
# 7102670
java/net/InetAddress/CheckJNI.java linux-all
diff --git a/test/TEST.groups b/test/TEST.groups
index c680117cc93280c079a6af567fae82c7a47e2545..77fae723f98dccc1a0b5f7b06eaf74c716b5e03c 100644
--- a/test/TEST.groups
+++ b/test/TEST.groups
@@ -325,7 +325,8 @@ needs_jdk = \
jdk/lambda/separate/Compiler.java \
sun/management/jdp/JdpTest.sh \
sun/management/jmxremote/bootstrap/JvmstatCountersTest.java \
- sun/management/jmxremote/bootstrap/LocalManagementTest.sh \
+ sun/management/jmxremote/bootstrap/LocalManagementTest.java \
+ sun/management/jmxremote/bootstrap/CustomLauncherTest.java \
sun/misc/JarIndex/metaInfFilenames/Basic.java \
sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java \
sun/reflect/CallerSensitive/CallerSensitiveFinder.java \
diff --git a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
index 16783aebc06e2858ddb7553c4a0339d02055a9d7..29b4e38b1f6ff40921ca640ef428af62cc8e9600 100644
--- a/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
+++ b/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java
@@ -25,24 +25,127 @@ package jdk.testlibrary;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Predicate;
import sun.management.VMManagement;
public final class ProcessTools {
+ private static final class LineForwarder extends StreamPumper.LinePump {
+ private final PrintStream ps;
+ private final String prefix;
+ LineForwarder(String prefix, PrintStream os) {
+ this.ps = os;
+ this.prefix = prefix;
+ }
+ @Override
+ protected void processLine(String line) {
+ ps.println("[" + prefix + "] " + line);
+ }
+ }
private ProcessTools() {
}
+ /**
+ *
Starts a process from its builder.
+ * The default redirects of STDOUT and STDERR are started
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @return Returns the initialized process
+ * @throws IOException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder)
+ throws IOException {
+ Process p = null;
+ try {
+ p = startProcess(name, processBuilder, null, -1, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException | TimeoutException e) {
+ // can't ever happen
+ }
+ return p;
+ }
+
+ /**
+ * Starts a process from its builder.
+ * The default redirects of STDOUT and STDERR are started
+ *
+ * It is possible to wait for the process to get to a warmed-up state
+ * via {@linkplain Predicate} condition on the STDOUT
+ *
+ * @param name The process name
+ * @param processBuilder The process builder
+ * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+ * Used to determine the moment the target app is
+ * properly warmed-up.
+ * It can be null - in that case the warmup is skipped.
+ * @param timeout The timeout for the warmup waiting
+ * @param unit The timeout {@linkplain TimeUnit}
+ * @return Returns the initialized {@linkplain Process}
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws TimeoutException
+ */
+ public static Process startProcess(String name,
+ ProcessBuilder processBuilder,
+ final Predicate linePredicate,
+ long timeout,
+ TimeUnit unit)
+ throws IOException, InterruptedException, TimeoutException {
+ Process p = processBuilder.start();
+ StreamPumper stdout = new StreamPumper(p.getInputStream());
+ StreamPumper stderr = new StreamPumper(p.getErrorStream());
+
+ stdout.addPump(new LineForwarder(name, System.out));
+ stderr.addPump(new LineForwarder(name, System.err));
+ final Phaser phs = new Phaser(1);
+ if (linePredicate != null) {
+ stdout.addPump(new StreamPumper.LinePump() {
+ @Override
+ protected void processLine(String line) {
+ if (linePredicate.test(line)) {
+ if (phs.getRegisteredParties() > 0) {
+ phs.arriveAndDeregister();
+ }
+ }
+ }
+ });
+ }
+ Future stdoutTask = stdout.process();
+ Future stderrTask = stderr.process();
+
+ try {
+ if (timeout > -1) {
+ phs.awaitAdvanceInterruptibly(0, timeout, unit);
+ }
+ } catch (TimeoutException | InterruptedException e) {
+ stdoutTask.cancel(true);
+ stderrTask.cancel(true);
+ throw e;
+ }
+
+ return p;
+ }
+
/**
* Pumps stdout and stderr from running the process into a String.
*
- * @param processHandler
+ * @param processBuilder
* ProcessHandler to run.
* @return Output from process.
* @throws IOException
@@ -69,22 +172,19 @@ public final class ProcessTools {
stdoutBuffer);
StreamPumper errPumper = new StreamPumper(process.getErrorStream(),
stderrBuffer);
- Thread outPumperThread = new Thread(outPumper);
- Thread errPumperThread = new Thread(errPumper);
-
- outPumperThread.setDaemon(true);
- errPumperThread.setDaemon(true);
- outPumperThread.start();
- errPumperThread.start();
+ Future outTask = outPumper.process();
+ Future errTask = errPumper.process();
try {
process.waitFor();
- outPumperThread.join();
- errPumperThread.join();
+ outTask.get();
+ errTask.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
+ } catch (ExecutionException e) {
+ throw new IOException(e);
}
return new OutputBuffer(stdoutBuffer.toString(),
diff --git a/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java b/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java
index 60adca4e3dae485ef15b0cb496cb1adfd4b17473..224dcb2824720de6d9596f620d80f1115b3574a5 100644
--- a/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java
+++ b/test/lib/testlibrary/jdk/testlibrary/StreamPumper.java
@@ -23,16 +23,65 @@
package jdk.testlibrary;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicBoolean;
public final class StreamPumper implements Runnable {
private static final int BUF_SIZE = 256;
- private final OutputStream out;
+ /**
+ * Pump will be called by the StreamPumper to process the incoming data
+ */
+ abstract public static class Pump {
+ abstract void register(StreamPumper d);
+ }
+
+ /**
+ * OutputStream -> Pump adapter
+ */
+ final public static class StreamPump extends Pump {
+ private final OutputStream out;
+ public StreamPump(OutputStream out) {
+ this.out = out;
+ }
+
+ @Override
+ void register(StreamPumper sp) {
+ sp.addOutputStream(out);
+ }
+ }
+
+ /**
+ * Used to process the incoming data line-by-line
+ */
+ abstract public static class LinePump extends Pump {
+ @Override
+ final void register(StreamPumper sp) {
+ sp.addLineProcessor(this);
+ }
+
+ abstract protected void processLine(String line);
+ }
+
private final InputStream in;
+ private final Set outStreams = new HashSet<>();
+ private final Set linePumps = new HashSet<>();
+
+ private final AtomicBoolean processing = new AtomicBoolean(false);
+ private final FutureTask processingTask = new FutureTask(this, null);
+
+ public StreamPumper(InputStream in) {
+ this.in = in;
+ }
/**
* Create a StreamPumper that reads from in and writes to out.
@@ -43,8 +92,8 @@ public final class StreamPumper implements Runnable {
* The stream to write to.
*/
public StreamPumper(InputStream in, OutputStream out) {
- this.in = in;
- this.out = out;
+ this(in);
+ this.addOutputStream(out);
}
/**
@@ -54,25 +103,97 @@ public final class StreamPumper implements Runnable {
*/
@Override
public void run() {
- int length;
- InputStream localIn = in;
- OutputStream localOut = out;
- byte[] buffer = new byte[BUF_SIZE];
-
- try {
- while ((length = localIn.read(buffer)) > 0 && !Thread.interrupted()) {
- localOut.write(buffer, 0, length);
+ try (BufferedInputStream is = new BufferedInputStream(in)) {
+ ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
+ byte[] buf = new byte[BUF_SIZE];
+ int len = 0;
+ int linelen = 0;
+
+ while ((len = is.read(buf)) > 0 && !Thread.interrupted()) {
+ for(OutputStream out : outStreams) {
+ out.write(buf, 0, len);
+ }
+ if (!linePumps.isEmpty()) {
+ int i = 0;
+ int lastcrlf = -1;
+ while (i < len) {
+ if (buf[i] == '\n' || buf[i] == '\r') {
+ int bufLinelen = i - lastcrlf - 1;
+ if (bufLinelen > 0) {
+ lineBos.write(buf, lastcrlf + 1, bufLinelen);
+ }
+ linelen += bufLinelen;
+
+ if (linelen > 0) {
+ lineBos.flush();
+ final String line = lineBos.toString();
+ linePumps.stream().forEach((lp) -> {
+ lp.processLine(line);
+ });
+ lineBos.reset();
+ linelen = 0;
+ }
+ lastcrlf = i;
+ }
+
+ i++;
+ }
+ if (lastcrlf == -1) {
+ lineBos.write(buf, 0, len);
+ linelen += len;
+ } else if (lastcrlf < len - 1) {
+ lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1);
+ linelen += len - lastcrlf - 1;
+ }
+ }
}
+
} catch (IOException e) {
- // Just abort if something like this happens.
e.printStackTrace();
} finally {
+ for(OutputStream out : outStreams) {
+ try {
+ out.flush();
+ } catch (IOException e) {}
+ }
try {
- localOut.flush();
in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ } catch (IOException e) {}
+ }
+ }
+
+ final void addOutputStream(OutputStream out) {
+ outStreams.add(out);
+ }
+
+ final void addLineProcessor(LinePump lp) {
+ linePumps.add(lp);
+ }
+
+ final public StreamPumper addPump(Pump ... pump) {
+ if (processing.get()) {
+ throw new IllegalStateException("Can not modify pumper while " +
+ "processing is in progress");
+ }
+ for(Pump p : pump) {
+ p.register(this);
}
+ return this;
+ }
+
+ final public Future process() {
+ if (!processing.compareAndSet(false, true)) {
+ throw new IllegalStateException("Can not re-run the processing");
+ }
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ processingTask.run();
+ }
+ });
+ t.setDaemon(true);
+ t.start();
+
+ return processingTask;
}
}
diff --git a/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.java b/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f77cce56308b53dc6c3c03f5c8591d6eaa9684d
--- /dev/null
+++ b/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 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.File;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import jdk.testlibrary.JdkFinder;
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * @test
+ * @bug 6434402 8004926
+ * @library ../../../../lib/testlibrary
+ * @build TestManager TestApplication CustomLauncherTest
+ * @run main CustomLauncherTest
+ * @author Jaroslav Bachorik
+ */
+public class CustomLauncherTest {
+ private static final String TEST_CLASSES = System.getProperty("test.classes");
+ private static final String TEST_JDK = System.getProperty("test.jdk");
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+ private static final String OSNAME = System.getProperty("os.name");
+ private static final String ARCH;
+ private static final String LIBARCH;
+
+ static {
+ // magic with os.arch
+ String osarch = System.getProperty("os.arch");
+ switch (osarch) {
+ case "i386":
+ case "i486":
+ case "i586":
+ case "i686":
+ case "i786":
+ case "i886":
+ case "i986": {
+ ARCH = "i586";
+ break;
+ }
+ case "x86_64":
+ case "amd64": {
+ ARCH = "amd64";
+ break;
+ }
+ default: {
+ ARCH = osarch;
+ }
+ }
+ LIBARCH = ARCH.equals("i586") ? "i386" : ARCH;
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (TEST_CLASSES == null || TEST_CLASSES.isEmpty()) {
+ System.out.println("Test is designed to be run from jtreg only");
+ return;
+ }
+
+ String PLATFORM = "";
+ switch (OSNAME.toLowerCase()) {
+ case "linux": {
+ PLATFORM = "linux";
+ break;
+ }
+ case "sunos": {
+ PLATFORM = "solaris";
+ break;
+ }
+ default: {
+ System.out.println("Test not designed to run on this operating " +
+ "system (" + OSNAME + "), skipping...");
+ return;
+ }
+ }
+
+ String LAUNCHER = TEST_SRC + File.separator + PLATFORM + "-" + ARCH +
+ File.separator + "launcher";
+
+ final FileSystem FS = FileSystems.getDefault();
+ final boolean hasLauncher = Files.isExecutable(FS.getPath(LAUNCHER));
+ if (!hasLauncher) {
+ System.out.println("Launcher [" + LAUNCHER + "] does not exist. Skipping the test.");
+ return;
+ }
+
+ Path libjvmPath = findLibjvm(FS);
+ if (libjvmPath == null) {
+ throw new Error("Unable to locate 'libjvm.so' in " + TEST_JDK);
+ }
+
+ Process serverPrc = null, clientPrc = null;
+
+ try {
+ System.out.println("Starting custom launcher:");
+ System.out.println("=========================");
+ System.out.println(" launcher : " + LAUNCHER);
+ System.out.println(" libjvm : " + libjvmPath.toString());
+ System.out.println(" classpath : " + TEST_CLASSES);
+ ProcessBuilder server = new ProcessBuilder(LAUNCHER, libjvmPath.toString(), TEST_CLASSES, "TestApplication");
+
+ final AtomicReference port = new AtomicReference<>();
+ final AtomicReference pid = new AtomicReference<>();
+
+ serverPrc = ProcessTools.startProcess(
+ "Launcher",
+ server,
+ (String line) -> {
+ if (line.startsWith("port:")) {
+ port.set(line.split("\\:")[1]);
+ } else if (line.startsWith("pid:")) {
+ pid.set(line.split("\\:")[1]);
+ } else if (line.startsWith("waiting")) {
+ return true;
+ }
+ return false;
+ },
+ 5,
+ TimeUnit.SECONDS
+ );
+
+ System.out.println("Attaching test manager:");
+ System.out.println("=========================");
+ System.out.println(" PID : " + pid.get());
+ System.out.println(" shutdown port : " + port.get());
+
+ ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
+ "-cp",
+ TEST_CLASSES +
+ File.pathSeparator +
+ TEST_JDK +
+ File.separator +
+ "lib" +
+ File.separator +
+ "tools.jar",
+ "TestManager",
+ pid.get(),
+ port.get(),
+ "true"
+ );
+
+ clientPrc = ProcessTools.startProcess(
+ "TestManager",
+ client,
+ (String line) -> line.startsWith("Starting TestManager for PID"),
+ 10,
+ TimeUnit.SECONDS
+ );
+
+ int clientExitCode = clientPrc.waitFor();
+ int serverExitCode = serverPrc.waitFor();
+
+ if (clientExitCode != 0 || serverExitCode != 0) {
+ throw new Error("Test failed");
+ }
+ } finally {
+ if (clientPrc != null) {
+ clientPrc.destroy();
+ clientPrc.waitFor();
+ }
+ if (serverPrc != null) {
+ serverPrc.destroy();
+ serverPrc.waitFor();
+ }
+ }
+ }
+
+ private static Path findLibjvm(FileSystem FS) {
+ Path libjvmPath = findLibjvm(FS.getPath(TEST_JDK, "jre", "lib", LIBARCH));
+ if (libjvmPath == null) {
+ libjvmPath = findLibjvm(FS.getPath(TEST_JDK, "lib", LIBARCH));
+ }
+ return libjvmPath;
+ }
+
+ private static Path findLibjvm(Path libPath) {
+ // ARCH/libjvm.so -> ARCH/server/libjvm.so -> ARCH/client/libjvm.so
+ Path libjvmPath = libPath.resolve("libjvm.so");
+ if (isFileOk(libjvmPath)) {
+ return libjvmPath;
+ }
+ libjvmPath = libPath.resolve("server/libjvm.so");
+ if (isFileOk(libjvmPath)) {
+ return libjvmPath;
+ }
+ libjvmPath = libPath.resolve("client/libjvm.so");
+ if (isFileOk(libPath)) {
+ return libjvmPath;
+ }
+
+ return null;
+ }
+
+ private static boolean isFileOk(Path path) {
+ return Files.isRegularFile(path) && Files.isReadable(path);
+ }
+}
diff --git a/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.sh b/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.sh
deleted file mode 100644
index 8622fba94a0fa17f26a2db9124689c0eac684642..0000000000000000000000000000000000000000
--- a/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.sh
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2006, 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 6434402
-# @summary Start an application using a custom launcher and check that
-# a management tool can connect.
-#
-# @build TestManager TestApplication
-# @run shell CustomLauncherTest.sh
-
-#
-# Check we are run from jtreg
-#
-if [ -z "${TESTCLASSES}" ]; then
- echo "Test is designed to be run from jtreg only"
- exit 0
-fi
-
-#
-# For now this test passes silently on Windows - this means the test only
-# has to locate libjvm.so. Also $! is not reliable on some releases of MKS.
-#{
-OS=`uname -s`
-if [ "$OS" != "Linux" -a "$OS" != "SunOS" ]; then
- echo "Test not designed to run on this operating system, skipping..."
- exit 0
-fi
-
-#
-# Locate the custom launcher for this platform
-#
-PLATFORM=unknown
-ARCH=unknown
-if [ "$OS" = "SunOS" ]; then
- PLATFORM=solaris
- case "`uname -p`" in
- i[3-9]86)
- ARCH=i586
- ;;
- sparc)
- ARCH=sparc
- ;;
- esac
-else
- PLATFORM=linux
- case "`uname -m`" in
- i[3-6]86)
- ARCH=i586
- ;;
- x86_64)
- ARCH=amd64
- ;;
- esac
-fi
-
-
-#
-# On x86 the native libraries are in lib/i386 for
-# compatability reasons
-#
-if [ "$ARCH" = "i586" ]; then
- LIBARCH="i386"
-else
- LIBARCH=$ARCH
-fi
-
-
-#
-# Check that a custom launcher exists for this platform
-#
-LAUNCHER="${TESTSRC}/${PLATFORM}-${ARCH}/launcher"
-if [ ! -x "${LAUNCHER}" ]; then
- echo "${LAUNCHER} not found"
- exit 0
-fi
-
-#
-# Locate the libjvm.so library
-#
-JVMLIB="${TESTJAVA}/jre/lib/${LIBARCH}/client/libjvm.so"
-if [ ! -f "${JVMLIB}" ]; then
- JVMLIB="${TESTJAVA}/jre/lib/${LIBARCH}/server/libjvm.so"
- if [ ! -f "${JVMLIB}" ]; then
- JVMLIB="${TESTJAVA}/lib/${LIBARCH}/client/libjvm.so"
- if [ ! -f "${JVMLIB}" ]; then
- JVMLIB="${TESTJAVA}/lib/${LIBARCH}/serevr/libjvm.so"
- if [ ! -f "${JVMLIB}" ]; then
- echo "Unable to locate libjvm.so in ${TESTJAVA}"
- exit 1
- fi
- fi
- fi
-fi
-
-#
-# Start the VM
-#
-outputfile=${TESTCLASSES}/Test.out
-rm -f ${outputfile}
-
-echo ''
-echo "Starting custom launcher..."
-echo " launcher: ${LAUNCHER}"
-echo " libjvm: ${JVMLIB}"
-echo "classpath: ${TESTCLASSES}"
-
-
-${LAUNCHER} ${JVMLIB} ${TESTCLASSES} TestApplication > ${outputfile} &
-pid=$!
-
-# Wait for managed VM to startup (although this looks like a potentially
-# infinate loop, the framework will eventually kill it)
-echo "Waiting for TestAppication to test..."
-attempts=0
-while true; do
- sleep 1
- port=`tail -1 ${outputfile}`
- if [ ! -z "$port" ]; then
- # In case of errors wait time for output to be flushed
- sleep 1
- cat ${outputfile}
- break
- fi
- attempts=`expr $attempts + 1`
- echo "Waiting $attempts second(s) ..."
-done
-
-# Start the manager - this should connect to VM
-${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES}:${TESTJAVA}/lib/tools.jar \
- TestManager $pid $port true
-if [ $? != 0 ]; then
- echo "Test failed"
- exit 1
-fi
-exit 0
diff --git a/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java b/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d7a518ce1cf4b70104a674f3fc00f8aa5ae7cfe
--- /dev/null
+++ b/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 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.File;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @test
+ * @library ../../../../lib/testlibrary
+ * @bug 5016507 6173612 6319776 6342019 6484550 8004926
+ * @summary Start a managed VM and test that a management tool can connect
+ * without connection or username/password details.
+ * TestManager will attempt a connection to the address obtained from
+ * both agent properties and jvmstat buffer.
+ * @build TestManager TestApplication
+ * @run main/timeout=300 LocalManagementTest
+ */
+
+import jdk.testlibrary.ProcessTools;
+
+public class LocalManagementTest {
+ private static final String TEST_CLASSES = System.getProperty("test.classes");
+ private static final String TEST_JDK = System.getProperty("test.jdk");
+
+ public static void main(String[] args) throws Exception {
+ int failures = 0;
+ for(Method m : LocalManagementTest.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(m.getModifiers()) &&
+ m.getName().startsWith("test")) {
+ m.setAccessible(true);
+ try {
+ System.out.println(m.getName());
+ System.out.println("==========");
+ Boolean rslt = (Boolean)m.invoke(null);
+ if (!rslt) {
+ System.err.println(m.getName() + " failed");
+ failures++;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ failures++;
+ }
+ }
+ }
+ if (failures > 0) {
+ throw new Error("Test failed");
+ }
+ }
+
+ private static boolean test1() throws Exception {
+ return doTest("-Dcom.sun.management.jmxremote");
+ }
+
+ private static boolean test2() throws Exception {
+ Path agentPath = findAgent();
+ if (agentPath != null) {
+ String agent = agentPath.toString();
+ return doTest("-javaagent:" + agent);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * no args (blank) - manager should attach and start agent
+ */
+ private static boolean test3() throws Exception {
+ return doTest(null);
+ }
+
+ /**
+ * sanity check arguments to management-agent.jar
+ */
+ private static boolean test4() throws Exception {
+ Path agentPath = findAgent();
+ if (agentPath != null) {
+ ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(
+ "-javaagent:" + agentPath.toString() +
+ "=com.sun.management.jmxremote.port=7775," +
+ "com.sun.management.jmxremote.authenticate=false," +
+ "com.sun.management.jmxremote.ssl=false",
+ "TestApplication",
+ "-exit"
+ );
+
+ Process prc = null;
+ try {
+ prc = ProcessTools.startProcess(
+ "TestApplication",
+ builder
+ );
+ int exitCode = prc.waitFor();
+ return exitCode == 0;
+ } finally {
+ if (prc != null) {
+ prc.destroy();
+ prc.waitFor();
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * use DNS-only name service
+ */
+ private static boolean test5() throws Exception {
+ return doTest("-Dsun.net.spi.namservice.provider.1=\"dns,sun\"");
+ }
+
+ private static Path findAgent() {
+ FileSystem FS = FileSystems.getDefault();
+ Path agentPath = FS.getPath(
+ TEST_JDK, "jre", "lib", "management-agent.jar"
+ );
+ if (!isFileOk(agentPath)) {
+ agentPath = FS.getPath(
+ TEST_JDK, "lib", "management-agent.jar"
+ );
+ }
+ if (!isFileOk(agentPath)) {
+ System.err.println("Can not locate management-agent.jar");
+ return null;
+ }
+ return agentPath;
+ }
+
+ private static boolean isFileOk(Path path) {
+ return Files.isRegularFile(path) && Files.isReadable(path);
+ }
+
+ private static boolean doTest(String arg) throws Exception {
+ List args = new ArrayList<>();
+ if (arg != null) {
+ args.add(arg);
+ }
+ args.add("TestApplication");
+ ProcessBuilder server = ProcessTools.createJavaProcessBuilder(
+ args.toArray(new String[args.size()])
+ );
+
+ Process serverPrc = null, clientPrc = null;
+ try {
+ final AtomicReference port = new AtomicReference<>();
+ final AtomicReference pid = new AtomicReference<>();
+
+ serverPrc = ProcessTools.startProcess(
+ "TestApplication",
+ server,
+ (String line) -> {
+ if (line.startsWith("port:")) {
+ port.set(line.split("\\:")[1]);
+ } else if (line.startsWith("pid:")) {
+ pid.set(line.split("\\:")[1]);
+ } else if (line.startsWith("waiting")) {
+ return true;
+ }
+ return false;
+ },
+ 5,
+ TimeUnit.SECONDS
+ );
+
+ System.out.println("Attaching test manager:");
+ System.out.println("=========================");
+ System.out.println(" PID : " + pid.get());
+ System.out.println(" shutdown port : " + port.get());
+
+ ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
+ "-cp",
+ TEST_CLASSES +
+ File.pathSeparator +
+ TEST_JDK +
+ File.separator +
+ "lib" +
+ File.separator +
+ "tools.jar",
+ "TestManager",
+ pid.get(),
+ port.get(),
+ "true"
+ );
+
+ clientPrc = ProcessTools.startProcess(
+ "TestManager",
+ client,
+ (String line) -> line.startsWith("Starting TestManager for PID"),
+ 10,
+ TimeUnit.SECONDS
+ );
+
+ int clientExitCode = clientPrc.waitFor();
+ int serverExitCode = serverPrc.waitFor();
+ return clientExitCode == 0 && serverExitCode == 0;
+ } finally {
+ if (clientPrc != null) {
+ System.out.println("Stopping process " + clientPrc);
+ clientPrc.destroy();
+ clientPrc.waitFor();
+ }
+ if (serverPrc != null) {
+ System.out.println("Stopping process " + serverPrc);
+ serverPrc.destroy();
+ serverPrc.waitFor();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/sun/management/jmxremote/bootstrap/LocalManagementTest.sh b/test/sun/management/jmxremote/bootstrap/LocalManagementTest.sh
deleted file mode 100644
index 7338cbe8600fb9326bb9177ff84e6b66f99b7c0b..0000000000000000000000000000000000000000
--- a/test/sun/management/jmxremote/bootstrap/LocalManagementTest.sh
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2004, 2006, 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 5016507 6173612 6319776 6342019 6484550
-# @summary Start a managed VM and test that a management tool can connect
-# without connection or username/password details.
-# TestManager will attempt a connection to the address obtained from
-# both agent properties and jvmstat buffer.
-#
-# @build TestManager TestApplication
-# @run shell/timeout=300 LocalManagementTest.sh
-
-
-doTest()
-{
- echo ''
-
- outputfile=${TESTCLASSES}/Test.out
- rm -f ${outputfile}
-
- # Start VM with given options
- echo "+ $JAVA ${TESTVMOPTS} $1 Test"
- $JAVA ${TESTVMOPTS} $1 TestApplication > ${outputfile}&
- pid=$!
-
- # Wait for managed VM to startup
- echo "Waiting for VM to startup..."
- attempts=0
- while true; do
- sleep 1
- port=`tail -1 ${outputfile}`
- if [ ! -z "$port" ]; then
- # In case of errors wait time for output to be flushed
- sleep 1
- cat ${outputfile}
- break
- fi
- attempts=`expr $attempts + 1`
- echo "Waiting $attempts second(s) ..."
- done
-
- # Start the manager - this should connect to VM
- sh -xc "$JAVA ${TESTVMOPTS} -classpath ${TESTCLASSES}:${TESTJAVA}/lib/tools.jar \
- TestManager $pid $port" 2>&1
- if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-}
-
-
-# Check we are run from jtreg
-if [ -z "${TESTCLASSES}" ]; then
- echo "Test is designed to be run from jtreg only"
- exit 0
-fi
-
-# For now this test passes silently on Windows - there are 2 reasons
-# to skip it :-
-#
-# 1. No jstat instrumentation buffers if FAT32 so need
-# -XX:+PerfBypassFileSystemCheck
-# 2. $! is used to get the pid of the created process but it's not
-# reliable on older versions of MKS. Also negative pids are returned
-# on Windows 98.
-
-os=`uname -s`
-if [ "$os" != "Linux" -a "$os" != "SunOS" ]; then
- echo "Test not designed to run on this operating system, skipping..."
- exit 0
-fi
-
-JAVA=${TESTJAVA}/bin/java
-CLASSPATH=${TESTCLASSES}
-export CLASSPATH
-
-failures=0
-
-# Test 1
-doTest "-Dcom.sun.management.jmxremote"
-
-# Test 2
-AGENT="${TESTJAVA}/jre/lib/management-agent.jar"
-if [ ! -f ${AGENT} ]; then
- AGENT="${TESTJAVA}/lib/management-agent.jar"
-fi
-doTest "-javaagent:${AGENT}"
-
-# Test 3 - no args (blank) - manager should attach and start agent
-doTest " "
-
-# Test 4 - sanity check arguments to management-agent.jar
-echo ' '
-sh -xc "${JAVA} ${TESTVMOPTS} -javaagent:${AGENT}=com.sun.management.jmxremote.port=7775,\
-com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false \
- TestApplication -exit" 2>&1
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# Test 5 - use DNS-only name service
-doTest "-Dsun.net.spi.namservice.provider.1=\"dns,sun\""
-
-#
-# Results
-#
-echo ''
-if [ $failures -gt 0 ];
- then echo "$failures test(s) failed";
- else echo "All test(s) passed"; fi
-exit $failures
-
diff --git a/test/sun/management/jmxremote/bootstrap/TestApplication.java b/test/sun/management/jmxremote/bootstrap/TestApplication.java
index 17816b9db1863d66d72b0f140efac133496b3263..5d6ca2b6a271dfe2881837ac199312bb377277c0 100644
--- a/test/sun/management/jmxremote/bootstrap/TestApplication.java
+++ b/test/sun/management/jmxremote/bootstrap/TestApplication.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -24,14 +24,18 @@
/*
*
*
- * A test "application" used by unit test LocalManagementTest.sh. This
- * application binds to some random port, prints the port number to
- * standard output, waits for somebody to connect, and then shuts down.
+ * A test "application" used by unit tests -
+ * LocalManagementTest.java, CustomLauncherTest.java.
+ * This application binds to some random port, prints its pid and
+ * the port number to standard output, waits for somebody to connect,
+ * and then shuts down.
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
+import jdk.testlibrary.ProcessTools;
+
public class TestApplication {
public static void main(String[] args) throws IOException {
// Some tests require the application to exit immediately
@@ -43,8 +47,17 @@ public class TestApplication {
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
- // signal test that we are started - do not remove this line!!
- System.out.println(port);
+ int pid = -1;
+ try {
+ pid = ProcessTools.getProcessId();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // signal test that we are started - do not remove these lines!!
+ System.out.println("port:" + port);
+ System.out.println("pid:" + pid);
+ System.out.println("waiting for the manager ...");
System.out.flush();
// wait for manager to connect
diff --git a/test/sun/management/jmxremote/bootstrap/TestManager.java b/test/sun/management/jmxremote/bootstrap/TestManager.java
index 379739adf29b2be5ee1601ee87a9a3fc604e15d9..4495c2d07fe60e9b567dd1677b0650568171dfb5 100644
--- a/test/sun/management/jmxremote/bootstrap/TestManager.java
+++ b/test/sun/management/jmxremote/bootstrap/TestManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -24,7 +24,8 @@
/*
*
*
- * A test "management tool" used by unit test LocalManagementTest.sh.
+ * A test "management tool" used by unit tests -
+ * LocalManagementTest.java, CustomLauncherTest.java
*
* Usage: java TestManager
*
@@ -32,8 +33,6 @@
* TCP port is used to shutdown the application.
*/
import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnector;
@@ -43,7 +42,6 @@ import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.File;
import java.io.IOException;
-import java.util.Properties;
// Sun specific
import com.sun.tools.attach.VirtualMachine;
@@ -111,6 +109,8 @@ public class TestManager {
"com.sun.management.jmxremote.localConnectorAddress";
public static void main(String[] args) throws Exception {
String pid = args[0]; // pid as a string
+ System.out.println("Starting TestManager for PID = " + pid);
+ System.out.flush();
VirtualMachine vm = VirtualMachine.attach(pid);
String agentPropLocalConnectorAddress = (String)
@@ -140,7 +140,6 @@ public class TestManager {
System.out.println("Testing the connector address from jvmstat buffer");
connect(pid, jvmstatLocalConnectorAddress);
-
// Shutdown application
int port = Integer.parseInt(args[1]);
System.out.println("Shutdown process via TCP port: " + port);
diff --git a/test/sun/management/jmxremote/bootstrap/linux-amd64/launcher b/test/sun/management/jmxremote/bootstrap/linux-amd64/launcher
new file mode 100644
index 0000000000000000000000000000000000000000..6df223c91c716644ceeed126c2971c48969fa295
Binary files /dev/null and b/test/sun/management/jmxremote/bootstrap/linux-amd64/launcher differ