changeset 12400:9d617cfd6717

Merge
author robm
date Thu, 03 Aug 2017 08:07:39 -0700
parents e8dad04faec9 a9d533a1ab7a
children dd6b8cddccc9
files
diffstat 15 files changed, 625 insertions(+), 157 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/bin/java.c	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/share/bin/java.c	Thu Aug 03 08:07:39 2017 -0700
@@ -650,9 +650,26 @@
 SetJvmEnvironment(int argc, char **argv) {
 
     static const char*  NMT_Env_Name    = "NMT_LEVEL_";
-
     int i;
     for (i = 0; i < argc; i++) {
+        char *arg = argv[i];
+        /*
+         * Since this must be a VM flag we stop processing once we see
+         * an argument the launcher would not have processed beyond (such
+         * as -version or -h), or an argument that indicates the following
+         * arguments are for the application (i.e. the main class name, or
+         * the -jar argument).
+         */
+        if ((i > 0 && *arg != '-')
+                || JLI_StrCmp(arg, "-version") == 0
+                || JLI_StrCmp(arg, "-fullversion") == 0
+                || JLI_StrCmp(arg, "-help") == 0
+                || JLI_StrCmp(arg, "-?") == 0
+                || JLI_StrCmp(arg, "-jar") == 0
+                || JLI_StrCmp(arg, "-X") == 0
+                ) {
+            return;
+        }
         /*
          * The following case checks for "-XX:NativeMemoryTracking=value".
          * If value is non null, an environmental variable set to this value
@@ -660,7 +677,6 @@
          * The argument is passed to the JVM, which will check validity.
          * The JVM is responsible for removing the env variable.
          */
-        char *arg = argv[i];
         if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) {
             int retval;
             // get what follows this parameter, include "="
--- a/src/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java	Thu Aug 03 08:07:39 2017 -0700
@@ -806,11 +806,12 @@
 
         // Paint the background for the tab area
         if ( tabPane.isOpaque() ) {
-            if (!c.isBackgroundSet() && (tabAreaBackground != null)) {
+            Color background = c.getBackground();
+            if (background instanceof UIResource && tabAreaBackground != null) {
                 g.setColor(tabAreaBackground);
             }
             else {
-                g.setColor( c.getBackground() );
+                g.setColor(background);
             }
             switch ( tabPlacement ) {
             case LEFT:
--- a/src/share/classes/sun/management/MemoryPoolImpl.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/share/classes/sun/management/MemoryPoolImpl.java	Thu Aug 03 08:07:39 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -304,8 +304,7 @@
                                           getCount());
         }
         void triggerAction() {
-            // Should not reach here
-            throw new AssertionError("Should not reach here");
+            // do nothing
         }
         void clearAction() {
             // do nothing
@@ -332,8 +331,7 @@
                                           gcSensor.getCount());
         }
         void triggerAction() {
-            // Should not reach here
-            throw new AssertionError("Should not reach here");
+            // do nothing
         }
         void clearAction() {
             // do nothing
--- a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Thu Aug 03 08:07:39 2017 -0700
@@ -270,7 +270,7 @@
 
         AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
         PublicKey currPubKey = cert.getPublicKey();
-        String currSigAlg = ((X509Certificate)cert).getSigAlgName();
+        String currSigAlg = x509Cert.getSigAlgName();
 
         // Check the signature algorithm and parameters against constraints.
         if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
--- a/src/solaris/native/java/net/NetworkInterface.c	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/solaris/native/java/net/NetworkInterface.c	Thu Aug 03 08:07:39 2017 -0700
@@ -1267,7 +1267,7 @@
   (JNIEnv *env, const char *ifname, const struct in_addr *addr,
    unsigned char *buf)
 {
-    static struct ifreq ifr;
+    struct ifreq ifr;
     int i, sock;
 
     if ((sock = openSocketWithFallback(env, ifname)) < 0) {
--- a/src/windows/native/java/net/DualStackPlainSocketImpl.c	Tue Jul 25 07:53:04 2017 -0700
+++ b/src/windows/native/java/net/DualStackPlainSocketImpl.c	Thu Aug 03 08:07:39 2017 -0700
@@ -48,6 +48,7 @@
     isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
                                      "(Ljava/net/InetAddress;I)V");
     CHECK_NULL(isa_ctorID);
+    initInetAddressIDs(env);
 
     // implement read timeout with select.
     isRcvTimeoutSupported = 0;
--- a/test/com/sun/jdi/LineNumberInfo.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/test/com/sun/jdi/LineNumberInfo.java	Thu Aug 03 08:07:39 2017 -0700
@@ -23,7 +23,7 @@
 
 /**
  *  @test
- *  @bug 4238644 4238643 4238641 4944198
+ *  @bug 4238644 4238643 4238641 4944198 8181500
  *  @summary Test javac regressions in the generation of line number info
  *  @author Gordon Hirsch
  *
@@ -72,6 +72,7 @@
         36,
         37,
         36,
+        37,
         40,
         41,
         42,
@@ -110,6 +111,7 @@
         85 ,
         93 ,
         96 ,
+        105,
         107,
         111,
         119,
--- a/test/java/lang/SecurityManager/CheckPackageAccess.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/test/java/lang/SecurityManager/CheckPackageAccess.java	Thu Aug 03 08:07:39 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -74,6 +74,8 @@
         "com.sun.org.apache.xalan.internal.xsltc.trax.",
         "com.sun.org.apache.xalan.internal.xsltc.util.",
         "com.sun.org.apache.xml.internal.res.",
+        "com.sun.org.apache.xml.internal.resolver.helpers.",
+        "com.sun.org.apache.xml.internal.resolver.readers.",
         "com.sun.org.apache.xml.internal.security.",
         "com.sun.org.apache.xml.internal.serializer.utils.",
         "com.sun.org.apache.xml.internal.utils.",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/NetworkInterface/GetMacAddress.java	Thu Aug 03 08:07:39 2017 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, 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 8182672
+ * @summary Java 8u121 on Linux intermittently returns null for MAC address
+ */
+
+import java.net.NetworkInterface;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.Phaser;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class GetMacAddress implements Callable<Exception> {
+    static final int NUM_THREADS = 5;
+    static final int NUM_ITERS = 100;
+    static volatile boolean failed; // false
+
+    final String threadName;
+    final NetworkInterface ni;
+    final Phaser startingGate;
+
+    public GetMacAddress(NetworkInterface ni, String name, Phaser phaser) {
+        this.ni = ni;
+        this.threadName = name;
+        this.startingGate = phaser;
+    }
+
+    @Override
+    public Exception call() {
+        int count = 0;
+        startingGate.arriveAndAwaitAdvance();
+        try {
+            for (int i = 0; i < NUM_ITERS; i++) {
+                ni.getMTU();
+                byte[] addr = ni.getHardwareAddress();
+                if (addr == null) {
+                    System.out.println(threadName + ". mac id is null");
+                    failed = true;
+                }
+                count = count + 1;
+                if (count % 100 == 0) {
+                    System.out.println(threadName + ". count is " + count);
+                }
+            }
+        } catch (Exception ex) {
+            System.out.println(threadName + ". Not expecting exception:" + ex.getMessage());
+            failed = true;
+            return ex;
+        }
+        return null;
+    }
+
+    static final Predicate<NetworkInterface> hasHardwareAddress = ni -> {
+        try {
+            if (ni.getHardwareAddress() == null) {
+                System.out.println("Not testing null addr: " + ni.getName());
+                return false;
+            }
+        } catch (Exception ex) {
+            System.out.println("Not testing: " + ni.getName() +
+                    " " + ex.getMessage());
+            return false;
+        }
+        return true;
+    };
+
+    public static Stream<NetworkInterface> getNetworkInterfacesAsStream() throws Exception {
+        // JDK 9 and later
+        //return NetworkInterface.networkInterfaces();
+        // pre JDK 9
+        return Collections.list(NetworkInterface.getNetworkInterfaces()).stream();
+    }
+
+    public static void main(String[] args) throws Exception {
+        List<NetworkInterface> toTest = getNetworkInterfacesAsStream()
+                        .filter(hasHardwareAddress)
+                        .collect(Collectors.toList());
+
+        ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
+
+        for (NetworkInterface ni : toTest) {
+            Phaser startingGate = new Phaser(NUM_THREADS);
+            System.out.println("Testing: " + ni.getName());
+            List<Callable<Exception>> list = new ArrayList<>();
+            for (int i = 0; i < NUM_THREADS; i++)
+                list.add(new GetMacAddress(ni, ni.getName() + "-Thread-" + i, startingGate));
+            List<Future<Exception>> futures = executor.invokeAll(list);
+            for (Future<Exception> f : futures) {
+                if (f.get() != null)
+                    f.get().printStackTrace(System.out);
+            }
+            if (failed)
+                break;
+        }
+        executor.shutdownNow();
+        if (!failed) {
+            System.out.println("PASSED - Finished all threads");
+        } else {
+            throw new RuntimeException("Failed");
+        }
+    }
+}
--- a/test/java/net/Socket/GetLocalAddress.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/test/java/net/Socket/GetLocalAddress.java	Thu Aug 03 08:07:39 2017 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4106601 8026245
+ * @bug 4106601 8026245 8071424
  * @run main/othervm GetLocalAddress
  * @run main/othervm -Djava.net.preferIPv4Stack=true GetLocalAddress
  * @run main/othervm -Djava.net.preferIPv6Addresses=true GetLocalAddress
@@ -39,6 +39,8 @@
     static int port;
 
     public static void main(String args[]) throws Exception {
+        testBindNull();
+
         boolean      error = true;
         int          linger = 65546;
         int          value = 0;
@@ -66,4 +68,19 @@
         }
     }
 
+    static void testBindNull() throws Exception {
+        try (Socket soc = new Socket()) {
+            soc.bind(null);
+            if (!soc.isBound())
+                throw new RuntimeException(
+                    "should be bound after bind(null)");
+            if (soc.getLocalPort() <= 0)
+                throw new RuntimeException(
+                   "bind(null) failed, local port: " + soc.getLocalPort());
+            if (soc.getLocalAddress() == null)
+                 throw new RuntimeException(
+                   "bind(null) failed, local address is null");
+        }
+    }
+
 }
--- a/test/javax/swing/JTabbedPane/8007563/Test8007563.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/test/javax/swing/JTabbedPane/8007563/Test8007563.java	Thu Aug 03 08:07:39 2017 -0700
@@ -21,9 +21,7 @@
  * questions.
  */
 
-import java.awt.Color;
-import java.awt.Point;
-import java.awt.Robot;
+import java.awt.*;
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import javax.swing.JFrame;
@@ -119,6 +117,20 @@
             }
 
         }
-        invokeLater(this);
+        SecondaryLoop secondaryLoop =
+                Toolkit.getDefaultToolkit().getSystemEventQueue()
+                        .createSecondaryLoop();
+        new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException e) {
+                }
+                secondaryLoop.exit();
+                invokeLater(Test8007563.this);
+            }
+        }.start();
+        secondaryLoop.enter();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/ws/8172297/Main.java	Thu Aug 03 08:07:39 2017 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017, 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 8172297
+ * @summary Test that carriage-return and new-line characters
+ * are preserved in webservice parameters
+ * @compile ws/HelloWorld.java ws/HelloWorldImpl.java Main.java
+ * @run testng/othervm Main
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URL;
+import java.util.concurrent.CountDownLatch;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Service;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import ws.HelloWorld;
+import ws.HelloWorldImpl;
+
+public class Main {
+
+    @Test
+    public void runTest() throws Exception {
+        //
+        CountDownLatch serverInitSignal = new CountDownLatch(1);
+        CountDownLatch testDoneSignal = new CountDownLatch(1);
+
+        WebserviceRunner serverThread = new WebserviceRunner(serverInitSignal, testDoneSignal);
+        (new Thread(serverThread)).start();
+
+        serverInitSignal.await();
+
+        boolean paramModified = runClientCode(serverThread.getPort());
+
+        testDoneSignal.countDown();
+
+        Assert.assertFalse(paramModified, "WS parameter was modified during round trip.");
+    }
+
+    /*
+     * Connects to launched web service endpoint, sends message with CR/NL symbols and
+     * checks if it was modified during the round trip client/server communication.
+     */
+    private boolean runClientCode(int port) throws Exception {
+        System.out.println("Launching WS client connection on " + port + " port");
+        URL url = new URL("http://localhost:" + port + "/ws/hello?wsdl");
+        QName qname = new QName("http://ws/", "HelloWorldImplService");
+        Service service = Service.create(url, qname);
+
+        HelloWorld hello = (HelloWorld) service.getPort(HelloWorld.class);
+
+        logStringContent("Client input parameter", WS_PARAM_VALUE);
+
+        String response = hello.getHelloWorldAsString(WS_PARAM_VALUE);
+        logStringContent("Client response parameter", response);
+
+        return !WS_PARAM_VALUE.equals(response);
+    }
+
+    /*
+     * Outputs the parameter value with newline and carriage-return symbols
+     * replaced with #CR and #NL text abbreviations.
+     */
+    private static void logStringContent(String description, String parameter) {
+        String readableContent = parameter.replaceAll("\r", "#CR")
+                                          .replaceAll("\n", "#NL");
+        System.out.println(description + ": '" + readableContent + "'");
+    }
+
+    /* Web service parameter value with newline and carriage-return symbols */
+    private final static String WS_PARAM_VALUE = "\r\r\n\r\r CarriageReturn and "
+                                                +"NewLine \r\n\n Test \r\r\r\r";
+
+    /*
+     * Web service server thread that publishes WS on vacant port and waits
+     * for client to finalize testing
+     */
+    class WebserviceRunner implements Runnable {
+        // Latch used to signalize when WS endpoint is initialized
+        private final CountDownLatch initSignal;
+        // Latch used to signalize when client completed testing
+        private final CountDownLatch doneSignal;
+        // Port where WS endpoint is published
+        private volatile int port = 0;
+
+        // Constructor
+        WebserviceRunner(CountDownLatch initSignal, CountDownLatch doneSignal) {
+            this.initSignal = initSignal;
+            this.doneSignal = doneSignal;
+        }
+
+        // Returns port of the published endpoint
+        public int getPort() {
+            return port;
+        }
+
+        /*
+         * Publish web service on vacant port and waits for the client to
+         * complete testing.
+         */
+        public void run() {
+            try {
+                // Find vacant port number
+                ServerSocket ss = new ServerSocket(0);
+                port = ss.getLocalPort();
+                ss.close();
+
+                // Publish WebService
+                System.out.println("Publishing WebService on " + port + " port");
+                Endpoint ep = Endpoint.publish("http://localhost:" + port + "/ws/hello", new HelloWorldImpl());
+
+                // Notify main thread that WS endpoint is published
+                initSignal.countDown();
+
+                // Wait for main thread to complete testing
+                System.out.println("Waiting for done signal from test client.");
+                doneSignal.await();
+
+                // Terminate WS endpoint
+                System.out.println("Got done signal from the client. Stopping WS endpoint.");
+                ep.stop();
+            } catch (IOException ioe) {
+                System.out.println("Failed to get vacant port number:" + ioe);
+            } catch (InterruptedException ie) {
+                System.out.println("Failed to wait for test completion:" + ie);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/ws/8172297/ws/HelloWorld.java	Thu Aug 03 08:07:39 2017 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package ws;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.jws.soap.SOAPBinding.Style;
+import javax.jws.soap.SOAPBinding.Use;
+
+//Web service endpoint interface
+@WebService
+@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
+public interface HelloWorld {
+
+    @WebMethod
+    String getHelloWorldAsString(String name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/ws/8172297/ws/HelloWorldImpl.java	Thu Aug 03 08:07:39 2017 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package ws;
+
+import javax.jws.WebService;
+
+// Simple web service implementation that echoes its parameter
+@WebService(endpointInterface = "ws.HelloWorld")
+public class HelloWorldImpl implements HelloWorld {
+
+    @Override
+    public String getHelloWorldAsString(String name) {
+        System.out.println("Server-side parameter value: '"
+                + name.replaceAll("\r", "#CR")
+                      .replaceAll("\n", "#NL") + "'");
+        return name;
+    }
+}
--- a/test/tools/launcher/TestSpecialArgs.java	Tue Jul 25 07:53:04 2017 -0700
+++ b/test/tools/launcher/TestSpecialArgs.java	Thu Aug 03 08:07:39 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,12 +23,14 @@
 
 /*
  * @test
- * @bug 7124089 7131021 8042469
- * @summary Checks for MacOSX specific flags are accepted or rejected, and
- *          MacOSX platforms specific environment is consistent.
+ * @bug 7124089 7131021 8042469 8066185
+ * @summary Checks for Launcher special flags, such as MacOSX specific flags,
+ *          and JVM NativeMemoryTracking flags.
  * @compile -XDignore.symbol.file TestSpecialArgs.java EnvironmentVariables.java
  * @run main TestSpecialArgs
  */
+import java.io.File;
+import java.io.FileNotFoundException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -36,10 +38,14 @@
 
 public class TestSpecialArgs extends TestHelper {
 
-    public static void main(String... args) {
+    public static void main(String... args) throws Exception {
+        new TestSpecialArgs().run(args);
+    }
+
+    @Test
+    void testDocking() {
         final Map<String, String> envMap = new HashMap<>();
         envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
-
         TestResult tr = doExec(envMap, javaCmd, "-XstartOnFirstThread", "-version");
         if (isMacOSX) {
             if (!tr.contains("In same thread")) {
@@ -69,140 +75,10 @@
                 throw new RuntimeException("Error: argument was accepted ????");
             }
         }
-
-        /*
-         * test argument : -XX:NativeMemoryTracking=value
-         * A JVM flag, comsumed by the JVM, but requiring launcher
-         * to set an environmental variable if and only if value is supplied.
-         * Test and order:
-         * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue
-         *    a) check for correct env variable name: "NMT_LEVEL_" + pid
-         *    b) check that "MyValue" was found in local env.
-         * 2) execute with invalid parameter: -XX:NativeMemoryTracking=
-         *    !) Won't find "NativeMemoryTracking:"
-         *       Code to create env variable not executed.
-         * 3) execute with invalid parameter: -XX:NativeMemoryTracking
-         *    !) Won't find "NativeMemoryTracking:"
-         *       Code to create env variable not executed.
-         * 4) give and invalid value and check to make sure JVM commented
-         */
-        { // NativeMemoryTracking
-            String launcherPidString = "launcher.pid=";
-            String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_";
-            String NMT_Option_Value = "off";
-            String myClassName = "helloworld";
-            boolean haveLauncherPid = false;
-
-            // === Run the tests ===
-
-            // ---Test 1a
-            tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value,
-                        "-version");
-
-            // get the PID from the env var we set for the JVM
-            String envVarPid = null;
-            for (String line : tr.testOutput) {
-                if (line.contains(envVarPidString)) {
-                    int sindex = envVarPidString.length();
-                    envVarPid = line.substring(sindex);
-                    break;
-                }
-            }
-            // did we find envVarPid?
-            if (envVarPid == null) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: failed to find env Var Pid in tracking info");
-            }
-            // we think we found the pid string.  min test, not "".
-            if (envVarPid.length() < 1) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: env Var Pid in tracking info is empty string");
-            }
-
-            /*
-             * On Linux, Launcher Tracking will print the PID.  Use this info
-             * to validate what we got as the PID in the Launcher itself.
-             * Linux is the only one that prints this, and trying to get it
-             * here for win is awful.  So let the linux test make sure we get
-             * the valid pid, and for non-linux, just make sure pid string is
-             * non-zero.
-             */
-            if (isLinux) {
-                // get what the test says is the launcher pid
-                String launcherPid = null;
-                for (String line : tr.testOutput) {
-                    int index = line.indexOf(launcherPidString);
-                    if (index >= 0) {
-                        int sindex = index + launcherPidString.length();
-                        int tindex = sindex + line.substring(sindex).indexOf("'");
-                        System.out.println("DEBUG INFO: sindex = " + sindex);
-                        System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex));
-                        System.out.println("DEBUG INFO: tindex = " + tindex);
-                        // DEBUG INFO
-                        System.out.println(tr);
-                        launcherPid = line.substring(sindex, tindex);
-                        break;
-                    }
-                }
-                if (launcherPid == null) {
-                    System.out.println(tr);
-                    throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info");
-                }
-
-                // did we create the env var with the correct pid?
-                if (!launcherPid.equals(envVarPid)) {
-                    System.out.println(tr);
-                    System.out.println("Error: wrong pid in creating env var");
-                    System.out.println("Error Info: launcherPid = " + launcherPid);
-                    System.out.println("Error Info: envVarPid   = " + envVarPid);
-                    throw new RuntimeException("Error: wrong pid in creating env var");
-                }
-            }
-
-
-            // --- Test 1b
-            if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: Valid param failed to set env variable");
-            }
-
-            // --- Test 2
-            tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=",
-                        "-version");
-            if (tr.contains("NativeMemoryTracking:")) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
-            }
-            if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: invalid param not checked by JVM");
-            }
-
-            // --- Test 3
-            tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking",
-                        "-version");
-            if (tr.contains("NativeMemoryTracking:")) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
-            }
-            if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: invalid param not checked by JVM");
-            }
-            // --- Test 4
-            tr = doExec(envMap,javaCmd, "-XX:NativeMemoryTracking=BADVALUE",
-                        "-version");
-            if (!tr.contains("expecting -XX:NativeMemoryTracking")) {
-                System.out.println(tr);
-                throw new RuntimeException("Error: invalid param did not get JVM Syntax error message");
-            }
-
-        } // NativeMemoryTracking
-
-
         // MacOSX specific tests ensue......
-        if (!isMacOSX)
+        if (!isMacOSX) {
             return;
+        }
         Set<String> envToRemove = new HashSet<>();
         Map<String, String> map = System.getenv();
         for (String s : map.keySet()) {
@@ -225,11 +101,187 @@
                 "APP_ICON_*", "TestAppIcon");
     }
 
-    static void runTest(Set<String> envToRemove, String... args) {
+    void runTest(Set<String> envToRemove, String... args) {
         TestResult tr = doExec(null, envToRemove, args);
         if (!tr.isOK()) {
             System.err.println(tr.toString());
             throw new RuntimeException("Test Fails");
         }
     }
+
+    @Test
+    void testNativeMemoryTracking() {
+        final Map<String, String> envMap = new HashMap<>();
+        envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
+        TestResult tr;
+        /*
+         * test argument : -XX:NativeMemoryTracking=value
+         * A JVM flag, comsumed by the JVM, but requiring launcher
+         * to set an environmental variable if and only if value is supplied.
+         * Test and order:
+         * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue
+         *    a) check for correct env variable name: "NMT_LEVEL_" + pid
+         *    b) check that "MyValue" was found in local env.
+         * 2) execute with invalid parameter: -XX:NativeMemoryTracking=
+         *    !) Won't find "NativeMemoryTracking:"
+         *       Code to create env variable not executed.
+         * 3) execute with invalid parameter: -XX:NativeMemoryTracking
+         *    !) Won't find "NativeMemoryTracking:"
+         *       Code to create env variable not executed.
+         * 4) give and invalid value and check to make sure JVM commented
+         */
+        String launcherPidString = "launcher.pid=";
+        String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_";
+        String NMT_Option_Value = "off";
+        String myClassName = "helloworld";
+        boolean haveLauncherPid = false;
+
+        // === Run the tests ===
+        // ---Test 1a
+        tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value,
+                "-version");
+
+        // get the PID from the env var we set for the JVM
+        String envVarPid = null;
+        for (String line : tr.testOutput) {
+            if (line.contains(envVarPidString)) {
+                int sindex = envVarPidString.length();
+                envVarPid = line.substring(sindex);
+                break;
+            }
+        }
+        // did we find envVarPid?
+        if (envVarPid == null) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: failed to find env Var Pid in tracking info");
+        }
+        // we think we found the pid string.  min test, not "".
+        if (envVarPid.length() < 1) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: env Var Pid in tracking info is empty string");
+        }
+
+        /*
+         * On Linux, Launcher Tracking will print the PID.  Use this info
+         * to validate what we got as the PID in the Launcher itself.
+         * Linux is the only one that prints this, and trying to get it
+         * here for win is awful.  So let the linux test make sure we get
+         * the valid pid, and for non-linux, just make sure pid string is
+         * non-zero.
+         */
+        if (isLinux) {
+            // get what the test says is the launcher pid
+            String launcherPid = null;
+            for (String line : tr.testOutput) {
+                int index = line.indexOf(launcherPidString);
+                if (index >= 0) {
+                    int sindex = index + launcherPidString.length();
+                    int tindex = sindex + line.substring(sindex).indexOf("'");
+                    System.out.println("DEBUG INFO: sindex = " + sindex);
+                    System.out.println("DEBUG INFO: searching substring: " + line.substring(sindex));
+                    System.out.println("DEBUG INFO: tindex = " + tindex);
+                    // DEBUG INFO
+                    System.out.println(tr);
+                    launcherPid = line.substring(sindex, tindex);
+                    break;
+                }
+            }
+            if (launcherPid == null) {
+                System.out.println(tr);
+                throw new RuntimeException("Error: failed to find launcher Pid in launcher tracking info");
+            }
+
+            // did we create the env var with the correct pid?
+            if (!launcherPid.equals(envVarPid)) {
+                System.out.println(tr);
+                System.out.println("Error: wrong pid in creating env var");
+                System.out.println("Error Info: launcherPid = " + launcherPid);
+                System.out.println("Error Info: envVarPid   = " + envVarPid);
+                throw new RuntimeException("Error: wrong pid in creating env var");
+            }
+        }
+
+        // --- Test 1b
+        if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: Valid param failed to set env variable");
+        }
+
+        // --- Test 2
+        tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=",
+                "-version");
+        if (tr.contains("NativeMemoryTracking:")) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
+        }
+        if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: invalid param not checked by JVM");
+        }
+
+        // --- Test 3
+        tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking",
+                "-version");
+        if (tr.contains("NativeMemoryTracking:")) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
+        }
+        if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: invalid param not checked by JVM");
+        }
+        // --- Test 4
+        tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=BADVALUE",
+                "-version");
+        if (!tr.contains("expecting -XX:NativeMemoryTracking")) {
+            System.out.println(tr);
+            throw new RuntimeException("Error: invalid param did not get JVM Syntax error message");
+        }
+    }
+
+    @Test
+    void testNMArgumentProcessing() throws FileNotFoundException {
+        TestResult tr = null;
+        // the direct invokers of the VM
+        String options[] = {
+            "-version", "-fullversion", "-help", "-?", "-X"
+        };
+        for (String option : options) {
+            tr = doExec(javaCmd, option, "-XX:NativeMemoryTracking=summary");
+            checkTestResult(tr);
+        }
+
+        // create a test jar
+        File jarFile = new File("test.jar");
+        createJar(jarFile, "public static void main(String... args){}");
+
+        // ones that involve main-class of some sort
+        tr = doExec(javaCmd, "-jar", jarFile.getName(),
+                "-XX:NativeMemoryTracking=summary");
+        checkTestResult(tr);
+
+        tr = doExec(javaCmd, "-cp", jarFile.getName(), "Foo",
+                "-XX:NativeMemoryTracking=summary");
+        checkTestResult(tr);
+
+        final Map<String, String> envMap = new HashMap<>();
+        // checkwith CLASSPATH set ie. no -cp or -classpath
+        envMap.put("CLASSPATH", ".");
+        tr = doExec(envMap, javaCmd, "Foo", "-XX:NativeMemoryTracking=summary");
+        checkTestResult(tr);
+
+        // make sure a missing class is handled correctly, because the class
+        // resolution is performed by the JVM.
+        tr = doExec(javaCmd, "AbsentClass", "-XX:NativeMemoryTracking=summary");
+        if (!tr.contains("Error: Could not find or load main class AbsentClass")) {
+            throw new RuntimeException("Test Fails");
+        }
+    }
+
+    void checkTestResult(TestResult tr) {
+        if (!tr.isOK()) {
+            System.err.println(tr.toString());
+            throw new RuntimeException("Test Fails");
+        }
+    }
 }