changeset 51648:b7b69bc93a2d

8210243: [TEST] rewrite com/sun/jdi shell tests to java version - step3 Reviewed-by: jcbeyler, cjplummer, sspitsyn
author amenkov
date Wed, 05 Sep 2018 10:39:16 -0700
parents 11ad7d302a94
children 8f594f75e054
files test/jdk/com/sun/jdi/BreakpointWithFullGC.java test/jdk/com/sun/jdi/DeoptimizeWalk.java test/jdk/com/sun/jdi/JdbArgTest.java test/jdk/com/sun/jdi/JdbArgTest.sh test/jdk/com/sun/jdi/JdbLockTest.java test/jdk/com/sun/jdi/JdbLockTest.sh test/jdk/com/sun/jdi/JdbMissStep.java test/jdk/com/sun/jdi/JdbMissStep.sh test/jdk/com/sun/jdi/JdbVarargsTest.java test/jdk/com/sun/jdi/JdbVarargsTest.sh test/jdk/com/sun/jdi/MixedSuspendTest.java test/jdk/com/sun/jdi/MixedSuspendTest.sh test/jdk/com/sun/jdi/NotAField.java test/jdk/com/sun/jdi/NotAField.sh test/jdk/com/sun/jdi/NullLocalVariable.java test/jdk/com/sun/jdi/NullLocalVariable.sh test/jdk/com/sun/jdi/lib/jdb/Jdb.java test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java test/jdk/com/sun/jdi/lib/jdb/JdbTest.java
diffstat 19 files changed, 703 insertions(+), 809 deletions(-) [+]
line wrap: on
line diff
--- a/test/jdk/com/sun/jdi/BreakpointWithFullGC.java	Wed Sep 05 10:17:11 2018 -0700
+++ b/test/jdk/com/sun/jdi/BreakpointWithFullGC.java	Wed Sep 05 10:39:16 2018 -0700
@@ -67,7 +67,7 @@
     }
 
     private BreakpointWithFullGC() {
-        super(new Jdb.LaunchOptions(DEBUGGEE_CLASS)
+        super(new LaunchOptions(DEBUGGEE_CLASS)
                      .addDebuggeeOptions(DEBUGGEE_OPTIONS));
     }
 
--- a/test/jdk/com/sun/jdi/DeoptimizeWalk.java	Wed Sep 05 10:17:11 2018 -0700
+++ b/test/jdk/com/sun/jdi/DeoptimizeWalk.java	Wed Sep 05 10:39:16 2018 -0700
@@ -33,7 +33,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import lib.jdb.Jdb;
 import lib.jdb.JdbCommand;
 import lib.jdb.JdbTest;
 
@@ -83,7 +82,7 @@
     }
 
     private DeoptimizeWalk() {
-        super(new Jdb.LaunchOptions(DEBUGGEE_CLASS)
+        super(new LaunchOptions(DEBUGGEE_CLASS)
                 .addDebuggeeOptions(DEBUGGEE_OPTIONS));
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/JdbArgTest.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2002, 2018, 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 4684386
+ * @summary TTY: jdb throws IllegalArumentException on cmd line args
+ * @comment converted from test/jdk/com/sun/jdi/JdbArgTest.sh
+ *
+ * @library /test/lib
+ * @run main/othervm JdbArgTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.Jdb;
+
+public class JdbArgTest {
+    public static void main(String argv[]) throws Exception {
+        try (Jdb jdb = new Jdb("Server", "0RBDebug", "subcontract,shutdown,transport")) {
+            jdb.waitForSimplePrompt(1, true);
+            jdb.quit();
+            new OutputAnalyzer(jdb.getJdbOutput())
+                    .shouldNotContain("IllegalArgumentException");
+        }
+    }
+}
--- a/test/jdk/com/sun/jdi/JdbArgTest.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2002, 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 4684386
-#  @summary TTY: jdb throws IllegalArumentException on cmd line args
-#  @author Jim/suvasis
-#  @run shell JdbArgTest.sh
-
-#Call this from anywhere to fail the test with an error message
-# usage: fail "reason why the test failed"
-fail() 
- { echo "The test failed :-("
-   echo "$*" 1>&2
-   echo "exit status was $status"
-   exit 1
- } #end of fail()
-
-#Call this from anywhere to pass the test with a message
-# usage: pass "reason why the test passed if applicable"
-pass() 
- { echo "The test passed!!!"
-   echo "$*" 1>&2
-   exit 0
- } #end of pass()
-
-# end of subroutines
-
-#Set appropriate jdk 
-
-if [ ! -z "${TESTJAVA}" ] ; then
-     jdk="$TESTJAVA"
-else
-     echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test."
-     exit 1
-fi
-
-echo quit | \
-   $TESTJAVA/bin/jdb Server 0RBDebug subcontract,shutdown,transport 2>&1 | \
-   fgrep IllegalArgumentException > /dev/null 2<&1
-
-if [ $? = 1 ] ; then
-   pass " This test passed and jbd got no IllegalArgumentException"
-fi
-
-fail "FAILED: jdb got an IllegalArgumentException"
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/JdbLockTest.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003, 2018, 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 4847812
+ * @summary TTY: jdb lock command displays incorrect data
+ * @comment converted from test/jdk/com/sun/jdi/JdbLockTest.sh
+ *
+ * @library /test/lib
+ * @compile -g JdbLockTest.java
+ * @run main/othervm JdbLockTest
+ */
+
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class JdbLockTestTarg {
+    static String jj = "jj";
+    public static void main(String args[]) {
+        synchronized(jj) {
+            sleeper xx = new sleeper();
+            xx.start();
+            // Give the sleeper a chance to run and get to
+            // the synchronized statement.
+            while(sleeper.started == 0) {
+                try {
+                    Thread.sleep(100);
+                } catch(InterruptedException ee) {
+                }
+            }
+            // At this bkpt, sleeper should be waiting on $classname.jj
+            System.out.println("Hello sailor");    // @1 breakpoint
+        }
+    }
+}
+
+class sleeper extends Thread {
+    public static int started = 0;
+    public void run() {
+        started = 1;
+        System.out.println("     sleeper starts sleeping");
+        synchronized(JdbLockTestTarg.jj) {
+            System.out.println("     sleeper got the lock");
+        }
+        System.out.println("     sleeper awakes");
+    }
+}
+
+public class JdbLockTest extends JdbTest {
+    public static void main(String argv[]) {
+        new JdbLockTest().run();
+    }
+
+    private JdbLockTest() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = JdbLockTestTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        setBreakpointsFromTestSource("JdbLockTest.java", 1);
+        // Run to breakpoint #1
+        jdb.command(JdbCommand.run());
+
+        // This should say that main owns the lock
+        // and the sleeper thread is waiting for it.
+        execCommand(JdbCommand.lock("JdbLockTestTarg.jj"))
+                .shouldNotContain("Waiting thread: main");
+    }
+}
--- a/test/jdk/com/sun/jdi/JdbLockTest.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2003, 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
-# 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 4847812
-#  @summary TTY: jdb lock command displays incorrect data
-#  @author Jim Holmlund
-#  @run shell JdbLockTest.sh
-
-# These are variables that can be set to control execution
-
-#pkg=untitled7
-classname=JdbLockTest
-compileOptions=-g
-#java="java_g"
-
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-public class $classname {
-    static String jj = "jj";
-    public static void main(String args[]) {
-        synchronized(jj) {
-            sleeper xx = new sleeper();
-            xx.start();
-            // Give the sleeper a chance to run and get to
-            // the synchronized statement.
-            while(sleeper.started == 0) {
-                try {
-                    Thread.sleep(100);
-                } catch(InterruptedException ee) {
-                }
-            }
-            // At this bkpt, sleeper should be waiting on $classname.jj
-            System.out.println("Hello sailor");    // @1 breakpoint
-        }
-    }
-}
-
-class sleeper extends Thread {
-    public static int started = 0;
-    public void run() {
-        started = 1;
-        System.out.println("     sleeper starts sleeping");
-        synchronized($classname.jj) {
-            System.out.println("     sleeper got the lock");
-        }
-        System.out.println("     sleeper awakes");
-    }
-}
-
-EOF
-}
-
-
-# drive jdb by sending cmds to it and examining its output
-dojdbCmds()
-{
-    setBkpts @1
-    runToBkpt @1
-    # This should say that main owns the lock
-    # and the sleeper thread is waiting for it.
-    cmd lock $classname.jj
-}
-
-
-mysetup()
-{
-    if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-    fi
-
-    for ii in . $TESTSRC $TESTSRC/.. ; do
-        if [ -r "$ii/ShellScaffold.sh" ] ; then
-            . $ii/ShellScaffold.sh
-            break
-        fi
-    done
-}
-
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-jdbFailIfPresent "Waiting thread: main"
-pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/JdbMissStep.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2002, 2018, 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 4762765
+ * @summary REGRESSION: jdb / jdi not stopping at some breakpoints and steps in j2sdk1.4.
+ * @comment converted from test/jdk/com/sun/jdi/JdbMissStep.sh
+ *
+ * @library /test/lib
+ * @compile -g JdbMissStep.java
+ * @run main/othervm JdbMissStep
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class JdbMissStepTarg {
+
+    public static void main(String args[]) {
+        JdbMissStepTarg dbb = new JdbMissStepTarg();
+        System.out.println("ANSWER IS: " + dbb.getIntVal());
+        jj2 gus = new jj2();
+        System.out.println("ANSWER2 IS: " + gus.getIntVal());
+    }
+
+    static int statVal;
+    int intVal = 89;
+    public int getIntVal() {
+        return intVal;  //@ 1 breakpoint
+    }
+
+    static class jj2 {
+        static int statVal;
+        int intVal = 89;
+        public int getIntVal() {
+            return intVal;  //@1 breakpoint  line 20
+        }
+    }
+}
+
+public class JdbMissStep extends JdbTest {
+    public static void main(String argv[]) {
+        new JdbMissStep().run();
+    }
+
+    private JdbMissStep() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = JdbMissStepTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        setBreakpoints(jdb, DEBUGGEE_CLASS + "$jj2", System.getProperty("test.src") + "/JdbMissStep.java", 1);
+
+        jdb.command(JdbCommand.run());
+        jdb.command(JdbCommand.step());
+
+        new OutputAnalyzer(jdb.getJdbOutput())
+                .shouldContain("Breakpoint hit");
+    }
+}
--- a/test/jdk/com/sun/jdi/JdbMissStep.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2002, 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
-# 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 4762765
-#  @summary REGRESSION: jdb / jdi not stopping at some breakpoints and steps in j2sdk1.4.
-#  @author Jim Holmlund
-#
-#  @key intermittent
-#  @run shell JdbMissStep.sh
-
-# These are variables that can be set to control execution
-
-#pkg=untitled7
-classname=JdbMissStep
-compileOptions=-g
-#java="java_g"
-
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-public class $classname {
-   
-    public static void main(String args[]) {
-        $classname dbb = new $classname();
-        System.out.println("ANSWER IS: " + dbb.getIntVal());
-        jj2 gus = new jj2();
-        System.out.println("ANSWER2 IS: " + gus.getIntVal());
-    }
-
-    static int statVal;
-    int intVal = 89;
-    public int getIntVal() {
-        return intVal;  //@ 1 breakpoint
-    }
-
-  static class jj2 {
-    static int statVal;
-    int intVal = 89;
-    public int getIntVal() {
-        return intVal;  //@1 breakpoint  line 20
-    }
-  }
-}
-
-EOF
-}
-
-
-# drive jdb by sending cmds to it and examining its output
-dojdbCmds()
-{
-    cmd stop at $classname'$jj2:20'
-    runToBkpt
-    cmd step
-}
-
-
-mysetup()
-{
-    if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-    fi
-
-    for ii in . $TESTSRC $TESTSRC/.. ; do
-        if [ -r "$ii/ShellScaffold.sh" ] ; then
-            . $ii/ShellScaffold.sh 
-            break
-        fi
-    done
-}
-
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-jdbFailIfNotPresent "Breakpoint hit"
-pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/JdbVarargsTest.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2003, 2018, 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 4870984
+ * @summary JPDA: Add support for RFE 4856541 - varargs
+ * @comment converted from test/jdk/com/sun/jdi/JdbVarargsTest.sh
+ *
+ * @library /test/lib
+ * @run main/othervm JdbVarargsTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class JdbVarargsTestTarg {
+
+    public static void main(String args[]) {
+        int ii = 0; // @1 breakpoint
+
+        // Call the varargs method so the bkpt will be hit
+        varString(new String[] {"a", "b"});
+    }
+
+    static String varString(String... ss) {
+        if (ss == null) {
+            return "-null-";
+        }
+        if (ss.length == 0) {
+            return "NONE";
+        }
+        String retVal = "";
+        for (int ii = 0; ii < ss.length; ii++) {
+            retVal += ss[ii];
+        }
+        return retVal;
+    }
+
+}
+
+public class JdbVarargsTest extends JdbTest {
+    public static void main(String argv[]) {
+        new JdbVarargsTest().run();
+    }
+
+    private JdbVarargsTest() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = JdbVarargsTestTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        setBreakpointsFromTestSource("JdbVarargsTest.java", 1);
+        // Run to breakpoint #1
+        jdb.command(JdbCommand.run());
+
+        // check that 'methods' shows the ...
+        jdb.command(JdbCommand.methods(DEBUGGEE_CLASS));
+
+        // check that we can call with no args
+        jdb.command(JdbCommand.eval(DEBUGGEE_CLASS + ".varString();"));
+
+        // check that we can call with var args
+        jdb.command(JdbCommand.eval(DEBUGGEE_CLASS + ".varString(\"aa\", \"bb\");"));
+
+        // check that we can stop in ...
+        jdb.command(JdbCommand.stopIn(DEBUGGEE_CLASS, "varString(java.lang.String...)"));
+
+        jdb.command(JdbCommand.cont());
+
+        new OutputAnalyzer(jdb.getJdbOutput())
+                .shouldContain("NONE")
+                .shouldContain("aabb")
+                .shouldContain(DEBUGGEE_CLASS + " varString(java.lang.String...)")
+                .shouldMatch("Breakpoint hit:.*varString\\(\\)");
+    }
+}
--- a/test/jdk/com/sun/jdi/JdbVarargsTest.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2003, 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 4870984
-#  @summary  JPDA: Add support for RFE 4856541 - varargs
-#
-#  @author jjh
-#
-#  @key intermittent
-#  @run shell JdbVarargsTest.sh
-
-classname=JdbVarargsTest
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-public class $classname {
-   
-    public static void main(String args[]) {
-        int ii = 0; // @1 breakpoint
-
-        // Call the varargs method so the bkpt will be hit
-        varString(new String[] {"a", "b"});
-    }
-
-    static String varString(String... ss) {
-        if (ss == null) {
-            return "-null-";
-        }
-        if (ss.length == 0) {
-            return "NONE";
-        }
-        String retVal = "";
-        for (int ii = 0; ii < ss.length; ii++) {
-            retVal += ss[ii];
-        }
-        return retVal;
-    }
-
-}
-EOF
-}
-
-
-# drive jdb by sending cmds to it and examining its output
-dojdbCmds()
-{
-    setBkpts @1
-    runToBkpt @1
-
-    # check that 'methods' shows the ...
-    cmd methods "$classname"
-
-    # check that we can call with no args
-    cmd eval  "$classname.varString();"
-
-    # check that we can call with var args
-    cmd eval "$classname.varString(\"aa\", \"bb\");"
-    
-    # check that we can stop in ...
-    cmd stop in "$classname.varString(java.lang.String...)"
-    contToBkpt
-}
-
-
-mysetup()
-{
-    if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-    fi
-
-    for ii in . $TESTSRC $TESTSRC/.. ; do
-        if [ -r "$ii/ShellScaffold.sh" ] ; then
-            . $ii/ShellScaffold.sh 
-            break
-        fi
-    done
-}
-
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-jdbFailIfNotPresent "NONE"
-jdbFailIfNotPresent "aabb"
-jdbFailIfNotPresent "$classname varString\(java\.lang\.String\.\.\.\)"
-jdbFailIfNotPresent 'Breakpoint hit:.*varString\(\)'
-pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/MixedSuspendTest.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2005, 2018, 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 6224859
+ * @summary JDWP: Mixing application suspends and debugger suspends can cause hangs
+ * @comment converted from test/jdk/com/sun/jdi/MixedSuspendTest.sh
+ *
+ * @library /test/lib
+ * @run main/othervm MixedSuspendTest
+ */
+
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class MixedSuspendTarg extends Thread {
+
+    static volatile boolean started = true;
+    static String lock = "startLock";
+
+    public static void main(String[] args){
+        System.out.println("Howdy from MixedSuspendTarg");
+
+        MixedSuspendTarg mytarg = new MixedSuspendTarg();
+
+        synchronized(lock) {
+            mytarg.start();
+            try {
+                lock.wait();
+            } catch(InterruptedException ee) {
+            }
+        }
+        mytarg.suspend();
+        bkpt();
+        System.out.println("Debuggee: resuming thread");
+
+        // If the bug occurs, this resume hangs in the back-end
+        mytarg.resume();
+        System.out.println("Debuggee: resumed thread");
+        synchronized(lock) {
+            started = false;
+        }
+        System.out.println("Debuggee: exitting, started = " + started);
+    }
+
+    public void run() {
+        synchronized(lock) {
+            lock.notifyAll();
+        }
+        while (true) {
+            synchronized(lock) {
+                if (!started) {
+                    break;
+                }
+                int i = 0;
+            }
+        }
+
+        System.out.println("Debuggee: end of thread");
+    }
+
+    static void bkpt() {
+        //System.out.println("bkpt reached, thread = " + this.getName());
+        int i = 0;   // @1 breakpoint
+    }
+}
+
+public class MixedSuspendTest extends JdbTest {
+    public static void main(String argv[]) {
+        new MixedSuspendTest().run();
+    }
+
+    private MixedSuspendTest() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = MixedSuspendTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        setBreakpointsFromTestSource("MixedSuspendTest.java", 1);
+        jdb.command(JdbCommand.run());
+        jdb.command(JdbCommand.cont().allowExit());
+
+        // This test fails by timing out.
+    }
+}
--- a/test/jdk/com/sun/jdi/MixedSuspendTest.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2005, 2015, 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 6224859
-# @key intermittent
-# @summary JDWP: Mixing application suspends and debugger suspends can cause hangs
-# @author Jim Holmlund
-#
-# @run build TestScaffold VMConnection TargetListener TargetAdapter
-# @run shell MixedSuspendTest.sh
-
-classname=MixedSuspendTarg
-
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-
-import java.util.*;
-
-public class $classname extends Thread {
-
-    static volatile boolean started = true;
-    static String lock = "startLock";
-
-    public static void main(String[] args){
-        System.out.println("Howdy from MixedSuspendTarg");
-
-        MixedSuspendTarg mytarg = new MixedSuspendTarg();
-
-        synchronized(lock) {
-            mytarg.start();
-            try {
-                lock.wait();
-            } catch(InterruptedException ee) {
-            }
-        }
-        mytarg.suspend();
-        bkpt();
-        System.out.println("Debuggee: resuming thread");
-
-        // If the bug occurs, this resume hangs in the back-end
-        mytarg.resume();
-        System.out.println("Debuggee: resumed thread");
-        synchronized(lock) {
-            started = false;
-        }
-        System.out.println("Debuggee: exitting, started = " + started);
-    }
-
-    public void run() {
-        synchronized(lock) {
-            lock.notifyAll();
-        }
-        while (true) {
-            synchronized(lock) {
-                if (!started) {
-                    break;
-                }
-                int i = 0;
-            }
-        }
-
-        System.out.println("Debuggee: end of thread");
-    }
-
-    static void bkpt() {
-        //System.out.println("bkpt reached, thread = " + this.getName());
-        int i = 0;   // @1 breakpoint
-    }
-}
-
-EOF
-}
-
-dojdbCmds()
-{
-    setBkpts @1
-    runToBkpt @1
-    cmd allowExit cont
-}
-
-
-mysetup()
-{
-    if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-    fi
-
-    for ii in . $TESTSRC $TESTSRC/.. ; do
-        if [ -r "$ii/ShellScaffold.sh" ] ; then
-            . $ii/ShellScaffold.sh
-            break
-        fi
-    done
-}
-
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-## This test fails by timing out.
-pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/NotAField.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2002, 2018, 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 4467887 4913748
+ * @summary TTY: NullPointerException at com.sun.tools.jdi.MirrorImpl.validateMirrors
+ * @comment converted from test/jdk/com/sun/jdi/NotAField.sh
+ *
+ * @library /test/lib
+ * @run main/othervm NotAField
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class NotAFieldTarg {
+    public static void main(String args[]) {
+        System.out.println("Hello, world!");
+    }
+}
+
+public class NotAField extends JdbTest {
+    public static void main(String argv[]) {
+        new NotAField().run();
+    }
+
+    private NotAField() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = NotAFieldTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        jdb.command(JdbCommand.stopIn(DEBUGGEE_CLASS, "main"));
+        jdb.command(JdbCommand.run());
+
+        // This works:
+        jdb.command(JdbCommand.print("java.lang.Class.reflectionFactory.hashCode()"));
+        // This should result in a ParseException: ("No such field in ..."):
+        jdb.command(JdbCommand.print("java.lang.Class.reflectionFactory.hashCode"));
+        jdb.contToExit(1);
+
+        new OutputAnalyzer(jdb.getJdbOutput())
+                .shouldContain("com.sun.tools.example.debug.expr.ParseException");
+    }
+}
--- a/test/jdk/com/sun/jdi/NotAField.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2002, 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
-# 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 4467887 4913748
-#  @summary TTY: NullPointerException at
-#           com.sun.tools.jdi.MirrorImpl.validateMirrors
-#  @author Tim Bell
-#  @key intermittent
-#  @run shell NotAField.sh
-#
-
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-public class $classname {
-    public static void main(String args[]) {
-        System.out.println("Hello, world!");
-    }
-}
-
-EOF
-}
-
-# This is called to feed cmds to jdb.
-dojdbCmds()
-{
-   #set -x
-   cmd stop in $classname.main
-   runToBkpt
-   #This works:
-   cmd print "java.lang.Class.reflectionFactory.hashCode()"
-   #This should result in a ParseException: ("No such field in ..."):
-   cmd print "java.lang.Class.reflectionFactory.hashCode"
-   cmd allowExit cont
-}
-
-mysetup()
-{
-   if [ -z "${TESTJAVA}" ] ; then
-      # TESTJAVA is not set, so the test is running stand-alone.
-      # TESTJAVA holds the path to the root directory of the build of the JDK
-      # to be tested.  That is, any java files run explicitly in this shell
-      # should use TESTJAVA in the path to the java interpreter.
-      # So, we'll set this to the JDK spec'd on the command line.  If none
-      # is given on the command line, tell the user that and use a default.
-      # THIS IS THE JDK BEING TESTED.
-      if [ -n "$1" ] ; then
-             TESTJAVA=$1
-         else
-             TESTJAVA=$JAVA_HOME
-      fi
-      TESTSRC=.
-      TESTCLASSES=.
-   fi
-   echo "JDK under test is: $TESTJAVA"
-
-   if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-   fi
-
-   if [ -r $TESTSRC/ShellScaffold.sh ] ; then
-        . $TESTSRC/ShellScaffold.sh 
-   elif [ -r $TESTSRC/../ShellScaffold.sh ] ; then
-        . $TESTSRC/../ShellScaffold.sh
-   fi
-}
-
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-jdbFailIfNotPresent "com.sun.tools.example.debug.expr.ParseException" 50
-pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/NullLocalVariable.java	Wed Sep 05 10:39:16 2018 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2002, 2018, 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 4690242 4695338
+ * @summary TTY: jdb throws NullPointerException when printing local variables
+ * @comment converted from test/jdk/com/sun/jdi/NullLocalVariable.sh
+ *
+ * @library /test/lib
+ * @compile -g NullLocalVariable.java
+ * @run main/othervm NullLocalVariable
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+class NullLocalVariableTarg {
+    public static final void main(String args[]) {
+        try {
+            System.out.println("hi!");               // @1 breakpoint
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            System.out.println("done");
+        }
+    }
+}
+
+public class NullLocalVariable extends JdbTest {
+    public static void main(String argv[]) {
+        new NullLocalVariable().run();
+    }
+
+    private NullLocalVariable() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    private static final String DEBUGGEE_CLASS = NullLocalVariableTarg.class.getName();
+
+    @Override
+    protected void runCases() {
+        setBreakpointsFromTestSource("NullLocalVariable.java", 1);
+        // Run to breakpoint #1
+        jdb.command(JdbCommand.run());
+
+        jdb.command(JdbCommand.next());
+        jdb.command(JdbCommand.next());
+        jdb.command(JdbCommand.locals());
+        jdb.contToExit(1);
+
+        new OutputAnalyzer(getDebuggeeOutput())
+                .shouldNotContain("Internal exception");
+    }
+}
--- a/test/jdk/com/sun/jdi/NullLocalVariable.sh	Wed Sep 05 10:17:11 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2002, 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
-# 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 4690242 4695338
-#  @summary TTY: jdb throws NullPointerException when printing local variables
-#  @author Tim Bell
-#
-#  @run shell NullLocalVariable.sh
-#
-classname=badscope
-
-createJavaFile()
-{
-    cat <<EOF > $classname.java.1
-public class badscope {
-    public static final void main(String args[]) {
-        try {
-            System.out.println("hi!");               // @1 breakpoint
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            System.out.println("done");
-        }
-    }
-}
-EOF
-}
-
-# This is called to feed cmds to jdb.
-dojdbCmds()
-{
-   #set -x
-   cmd stop at badscope:4   ; $sleepcmd
-   runToBkpt                ; $sleepcmd
-   cmd next                 ; $sleepcmd
-   cmd next                 ; $sleepcmd
-   cmd locals               ; $sleepcmd
-   cmd allowExit cont
-}
-
-mysetup()
-{
-    compileOptions=-g
-    if [ -z "$TESTSRC" ] ; then
-        TESTSRC=.
-    fi
-
-    for ii in . $TESTSRC $TESTSRC/.. ; do
-        if [ -r "$ii/ShellScaffold.sh" ] ; then
-            . $ii/ShellScaffold.sh
-            break
-        fi
-    done
-}
-# You could replace this next line with the contents
-# of ShellScaffold.sh and this script will run just the same.
-mysetup
-
-runit
-jdbFailIfPresent "Internal exception" 50
-pass
--- a/test/jdk/com/sun/jdi/lib/jdb/Jdb.java	Wed Sep 05 10:17:11 2018 -0700
+++ b/test/jdk/com/sun/jdi/lib/jdb/Jdb.java	Wed Sep 05 10:39:16 2018 -0700
@@ -33,88 +33,22 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.Utils;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.StreamPumper;
 
-public class Jdb {
-
-    public static class LaunchOptions {
-        public final String debuggeeClass;
-        public final List<String> debuggeeOptions = new LinkedList<>();
-
-        public LaunchOptions(String debuggeeClass) {
-            this.debuggeeClass = debuggeeClass;
+public class Jdb implements AutoCloseable {
+    public Jdb(String... args) {
+        ProcessBuilder pb = new ProcessBuilder(JDKToolFinder.getTestJDKTool("jdb"));
+        pb.command().addAll(Arrays.asList(args));
+        try {
+            jdb = pb.start();
+        } catch (IOException ex) {
+            throw new RuntimeException("failed to launch pdb", ex);
         }
-        public LaunchOptions addDebuggeeOption(String option) {
-            debuggeeOptions.add(option);
-            return this;
-        }
-        public LaunchOptions addDebuggeeOptions(String[] options) {
-            debuggeeOptions.addAll(Arrays.asList(options));
-            return this;
-        }
-    }
-
-    public static Jdb launchLocal(LaunchOptions options) {
-        return new Jdb(options);
-    }
-
-    public static Jdb launchLocal(String debuggeeClass) {
-        return new Jdb(new LaunchOptions(debuggeeClass));
-    }
-
-    public Jdb(LaunchOptions options) {
-        /* run debuggee as:
-            java -agentlib:jdwp=transport=dt_socket,address=0,server=n,suspend=y <debuggeeClass>
-        it reports something like : Listening for transport dt_socket at address: 60810
-        after that connect jdb by:
-            jdb -connect com.sun.jdi.SocketAttach:port=60810
-        */
-        // launch debuggee
-        List<String> debuggeeArgs = new LinkedList<>();
-        // specify address=0 to automatically select free port
-        debuggeeArgs.add("-agentlib:jdwp=transport=dt_socket,address=0,server=y,suspend=y");
-        debuggeeArgs.addAll(options.debuggeeOptions);
-        debuggeeArgs.add(options.debuggeeClass);
-        ProcessBuilder pbDebuggee = ProcessTools.createJavaProcessBuilder(true, debuggeeArgs.toArray(new String[0]));
-
-        // debuggeeListen[0] - transport, debuggeeListen[1] - address
-        String[] debuggeeListen = new String[2];
-        Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b");
         try {
-            debuggee = ProcessTools.startProcess("debuggee", pbDebuggee,
-                    s -> debuggeeOutput.add(s),  // output consumer
-                    s -> {  // warm-up predicate
-                        Matcher m = listenRegexp.matcher(s);
-                        if (!m.matches()) {
-                            return false;
-                        }
-                        debuggeeListen[0] = m.group(1);
-                        debuggeeListen[1] = m.group(2);
-                        return true;
-                    },
-                    30, TimeUnit.SECONDS);
-        } catch (IOException | InterruptedException | TimeoutException ex) {
-            throw new RuntimeException("failed to launch debuggee", ex);
-        }
-
-        // launch jdb
-        try {
-            ProcessBuilder pb = new ProcessBuilder(JDKToolFinder.getTestJDKTool("jdb"));
-            pb.command().add("-connect");
-            pb.command().add("com.sun.jdi.SocketAttach:port=" + debuggeeListen[1]);
-            System.out.println("Launching jdb:" + pb.command().stream().collect(Collectors.joining(" ")));
-            try {
-                jdb = pb.start();
-            } catch (IOException ex) {
-                throw new RuntimeException("failed to launch pdb", ex);
-            }
             StreamPumper stdout = new StreamPumper(jdb.getInputStream());
             StreamPumper stderr = new StreamPumper(jdb.getErrorStream());
 
@@ -126,19 +60,16 @@
 
             inputWriter = new PrintWriter(jdb.getOutputStream(), true);
         } catch (Throwable ex) {
-            // terminate debuggee if something went wrong
-            debuggee.destroy();
+            // terminate jdb if something went wrong
+            jdb.destroy();
             throw ex;
         }
     }
 
     private final Process jdb;
-    private final Process debuggee;
     private final OutputHandler outputHandler = new OutputHandler();
     private final PrintWriter inputWriter;
-    // contains all jdb output (to be used by getJdbOutput())
     private final List<String> jdbOutput = new LinkedList<>();
-    private final List<String> debuggeeOutput = new LinkedList<>();
 
     private static final String lineSeparator = System.getProperty("line.separator");
     // wait time before check jdb output (in ms)
@@ -146,8 +77,6 @@
     // max time to wait for  jdb output (in ms)
     private static long timeout = 60000;
 
-    // jdb prompt when debuggee is not started nor suspended after breakpoint
-    public static final String SIMPLE_PROMPT = "> ";
     // pattern for message of a breakpoint hit
     public static final String BREAKPOINT_HIT = "Breakpoint hit:";
     // pattern for message of an application exit
@@ -156,6 +85,11 @@
     public static final String APPLICATION_DISCONNECTED = "The application has been disconnected";
 
 
+    @Override
+    public void close() throws Exception {
+        shutdown();
+    }
+
     // waits until the process shutdown or crash
     public boolean waitFor(long timeout, TimeUnit unit) {
         try {
@@ -178,18 +112,6 @@
                 }
             }
         }
-        // shutdown debuggee
-        if (debuggee.isAlive()) {
-            try {
-                debuggee.waitFor(Utils.adjustTimeout(10), TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                // ignore
-            } finally {
-                if (debuggee.isAlive()) {
-                    debuggee.destroy();
-                }
-            }
-        }
     }
 
 
@@ -231,6 +153,16 @@
     private final String promptPattern = "[a-zA-Z0-9_-][a-zA-Z0-9_-]*\\[[1-9][0-9]*\\] [ >]*$";
     private final Pattern promptRegexp = Pattern.compile(promptPattern);
     public List<String> waitForPrompt(int lines, boolean allowExit) {
+        return waitForPrompt(lines, allowExit, promptRegexp);
+    }
+
+    // jdb prompt when debuggee is not started and is not suspended after breakpoint
+    private static final String SIMPLE_PROMPT = "> ";
+    public List<String> waitForSimplePrompt(int lines, boolean allowExit) {
+        return waitForPrompt(lines, allowExit, Pattern.compile(SIMPLE_PROMPT));
+    }
+
+    private List<String> waitForPrompt(int lines, boolean allowExit, Pattern promptRegexp) {
         long startTime = System.currentTimeMillis();
         while (System.currentTimeMillis() - startTime < timeout) {
             try {
@@ -333,11 +265,6 @@
         return jdbOutput.stream().collect(Collectors.joining(lineSeparator));
     }
 
-    // returns the whole debuggee output as a string
-    public String getDebuggeeOutput() {
-        return debuggeeOutput.stream().collect(Collectors.joining(lineSeparator));
-    }
-
     // handler for out/err of the pdb process
     private class OutputHandler extends OutputStream {
         // there are 2 buffers:
--- a/test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java	Wed Sep 05 10:17:11 2018 -0700
+++ b/test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java	Wed Sep 05 10:39:16 2018 -0700
@@ -197,6 +197,14 @@
         return new JdbCommand("set " + lvalue + " = " + expr);
     }
 
+    public static JdbCommand lock(String expr) {
+        return new JdbCommand("lock " + expr);
+    }
+
+    public static JdbCommand methods(String classId) {
+        return new JdbCommand("methods " + classId);
+    }
+
     // trace [go] methods [thread]
     //                           -- trace method entries and exits.
     //                           -- All threads are suspended unless 'go' is specified
@@ -226,4 +234,9 @@
     public static JdbCommand untrace() {
         return new JdbCommand("untrace");
     }
+
+    // watch [access|all] <class id>.<field name>
+    public static JdbCommand watch(String classId, String fieldName) {
+        return new JdbCommand("watch " + classId + "." + fieldName);
+    }
 }
--- a/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java	Wed Sep 05 10:17:11 2018 -0700
+++ b/test/jdk/com/sun/jdi/lib/jdb/JdbTest.java	Wed Sep 05 10:39:16 2018 -0700
@@ -23,28 +23,54 @@
 
 package lib.jdb;
 
+import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
 
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 public abstract class JdbTest {
 
-    public JdbTest(Jdb.LaunchOptions jdbOptions) {
-        this.jdbOptions= jdbOptions;
-        debuggeeClass = jdbOptions.debuggeeClass;
+    public static class LaunchOptions {
+        public final String debuggeeClass;
+        public final List<String> debuggeeOptions = new LinkedList<>();
+
+        public LaunchOptions(String debuggeeClass) {
+            this.debuggeeClass = debuggeeClass;
+        }
+        public LaunchOptions addDebuggeeOption(String option) {
+            debuggeeOptions.add(option);
+            return this;
+        }
+        public LaunchOptions addDebuggeeOptions(String[] options) {
+            debuggeeOptions.addAll(Arrays.asList(options));
+            return this;
+        }
+    }
+
+    public JdbTest(LaunchOptions launchOptions) {
+        this.launchOptions= launchOptions;
+        debuggeeClass = launchOptions.debuggeeClass;
     }
     public JdbTest(String debuggeeClass) {
-        this(new Jdb.LaunchOptions(debuggeeClass));
+        this(new LaunchOptions(debuggeeClass));
     }
 
-    private final Jdb.LaunchOptions jdbOptions;
     protected Jdb jdb;
-    protected final String debuggeeClass;   // shortland for jdbOptions.debuggeeClass
+    protected Process debuggee;
+    private final List<String> debuggeeOutput = new LinkedList<>();
+    private final LaunchOptions launchOptions;
+    protected final String debuggeeClass;   // shortland for launchOptions.debuggeeClass
 
     // returns the whole jdb output as a string
     public String getJdbOutput() {
@@ -53,7 +79,7 @@
 
     // returns the whole debuggee output as a string
     public String getDebuggeeOutput() {
-        return jdb == null ? "" : jdb.getDebuggeeOutput();
+        return debuggeeOutput.stream().collect(Collectors.joining(lineSeparator));
     }
 
     public void run() {
@@ -66,10 +92,50 @@
     }
 
     protected void setup() {
-        jdb = Jdb.launchLocal(jdbOptions);
+        /* run debuggee as:
+            java -agentlib:jdwp=transport=dt_socket,address=0,server=n,suspend=y <debuggeeClass>
+        it reports something like : Listening for transport dt_socket at address: 60810
+        after that connect jdb by:
+            jdb -connect com.sun.jdi.SocketAttach:port=60810
+        */
+        // launch debuggee
+        List<String> debuggeeArgs = new LinkedList<>();
+        // specify address=0 to automatically select free port
+        debuggeeArgs.add("-agentlib:jdwp=transport=dt_socket,address=0,server=y,suspend=y");
+        debuggeeArgs.addAll(launchOptions.debuggeeOptions);
+        debuggeeArgs.add(launchOptions.debuggeeClass);
+        ProcessBuilder pbDebuggee = ProcessTools.createJavaProcessBuilder(true, debuggeeArgs.toArray(new String[0]));
+
+        // debuggeeListen[0] - transport, debuggeeListen[1] - address
+        String[] debuggeeListen = new String[2];
+        Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b");
+        try {
+            debuggee = ProcessTools.startProcess("debuggee", pbDebuggee,
+                    s -> debuggeeOutput.add(s),  // output consumer
+                    s -> {  // warm-up predicate
+                        Matcher m = listenRegexp.matcher(s);
+                        if (!m.matches()) {
+                            return false;
+                        }
+                        debuggeeListen[0] = m.group(1);
+                        debuggeeListen[1] = m.group(2);
+                        return true;
+                    },
+                    30, TimeUnit.SECONDS);
+        } catch (IOException | InterruptedException | TimeoutException ex) {
+            throw new RuntimeException("failed to launch debuggee", ex);
+        }
+
+        // launch jdb
+        try {
+            jdb = new Jdb("-connect", "com.sun.jdi.SocketAttach:port=" + debuggeeListen[1]);
+        } catch (Throwable ex) {
+            // terminate debuggee if something went wrong
+            debuggee.destroy();
+            throw ex;
+        }
         // wait while jdb is initialized
         jdb.waitForPrompt(1, false);
-
     }
 
     protected abstract void runCases();
@@ -78,6 +144,18 @@
         if (jdb != null) {
             jdb.shutdown();
         }
+        // shutdown debuggee
+        if (debuggee != null && debuggee.isAlive()) {
+            try {
+                debuggee.waitFor(Utils.adjustTimeout(10), TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                // ignore
+            } finally {
+                if (debuggee.isAlive()) {
+                    debuggee.destroy();
+                }
+            }
+        }
     }
 
     protected static final String lineSeparator = System.getProperty("line.separator");
@@ -130,6 +208,7 @@
         List<String> reply = jdb.command(cmd);
         return new OutputAnalyzer(reply.stream().collect(Collectors.joining(lineSeparator)));
     }
+
     // helpers for "eval" jdb command.
     // executes "eval <expr>" and verifies output contains the specified text
     protected void evalShouldContain(String expr, String expectedString) {