changeset 49448:e6a79c032ac6

Merge
author jwilhelm
date Mon, 19 Feb 2018 04:50:50 +0100
parents ea85eed8b012 54b423e1c4cf
children f7caa2aecc86
files
diffstat 15 files changed, 297 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Feb 19 09:46:10 2018 +0100
+++ b/.hgtags	Mon Feb 19 04:50:50 2018 +0100
@@ -469,3 +469,4 @@
 3eae36c6baa5f916a3024cf1513e22357e00185d jdk-10+41
 4b62b815b4f49970b91a952929cf50115c263cb3 jdk-10+42
 107413b070b92c88bde6230ceb4a19b579781068 jdk-10+43
+dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1
--- a/make/InitSupport.gmk	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/InitSupport.gmk	Mon Feb 19 04:50:50 2018 +0100
@@ -361,6 +361,12 @@
 
   BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
 
+  ifneq ($(CUSTOM_ROOT), )
+    topdir=$(CUSTOM_ROOT)
+  else
+    topdir=$(TOPDIR)
+  endif
+
   # Parse COMPARE_BUILD into COMPARE_BUILD_*
   # Syntax: COMPARE_BUILD=CONF=<configure options>:PATCH=<patch file>:
   #         MAKE=<make targets>:COMP_OPTS=<compare script options>:
@@ -373,7 +379,7 @@
   # FAIL can be set to false to have the return value of compare be ignored.
   define ParseCompareBuild
     ifneq ($$(COMPARE_BUILD), )
-      COMPARE_BUILD_OUTPUTDIR := $(TOPDIR)/build/compare-build/$(CONF_NAME)
+      COMPARE_BUILD_OUTPUTDIR := $(topdir)/build/compare-build/$(CONF_NAME)
       COMPARE_BUILD_FAIL := true
 
       ifneq ($$(findstring :, $$(COMPARE_BUILD)), )
@@ -412,9 +418,9 @@
         endif
       endif
       ifneq ($$(COMPARE_BUILD_PATCH), )
-        ifneq ($$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH)), )
+        ifneq ($$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH)), )
           # Assume relative path, if file exists
-          COMPARE_BUILD_PATCH := $$(wildcard $$(TOPDIR)/$$(COMPARE_BUILD_PATCH))
+          COMPARE_BUILD_PATCH := $$(wildcard $$(topdir)/$$(COMPARE_BUILD_PATCH))
         else ifeq ($$(wildcard $$(COMPARE_BUILD_PATCH)), )
           $$(error Patch file $$(COMPARE_BUILD_PATCH) does not exist)
         endif
@@ -431,9 +437,9 @@
         # Apply patch, if any
 	$(if $(COMPARE_BUILD_PATCH), $(PATCH) -p1 < $(COMPARE_BUILD_PATCH))
         # Move the first build away temporarily
-	$(RM) -r $(TOPDIR)/build/.compare-build-temp
-	$(MKDIR) -p $(TOPDIR)/build/.compare-build-temp
-	$(MV) $(OUTPUTDIR) $(TOPDIR)/build/.compare-build-temp
+	$(RM) -r $(topdir)/build/.compare-build-temp
+	$(MKDIR) -p $(topdir)/build/.compare-build-temp
+	$(MV) $(OUTPUTDIR) $(topdir)/build/.compare-build-temp
         # Restore an old compare-build, or create a new compare-build directory.
 	if test -d $(COMPARE_BUILD_OUTPUTDIR); then \
 	  $(MV) $(COMPARE_BUILD_OUTPUTDIR) $(OUTPUTDIR); \
@@ -443,7 +449,7 @@
         # Re-run configure with the same arguments (and possibly some additional),
         # must be done after patching.
 	( cd $(OUTPUTDIR) && PATH="$(ORIGINAL_PATH)" \
-	    $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
+	    $(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
   endef
 
   # Cleanup after a compare build
@@ -451,10 +457,10 @@
         # If running with a COMPARE_BUILD patch, reverse-apply it
 	$(if $(COMPARE_BUILD_PATCH), $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH))
         # Move this build away and restore the original build
-	$(MKDIR) -p $(TOPDIR)/build/compare-build
+	$(MKDIR) -p $(topdir)/build/compare-build
 	$(MV) $(OUTPUTDIR) $(COMPARE_BUILD_OUTPUTDIR)
-	$(MV) $(TOPDIR)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR)
-	$(RM) -r $(TOPDIR)/build/.compare-build-temp
+	$(MV) $(topdir)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUTDIR)
+	$(RM) -r $(topdir)/build/.compare-build-temp
   endef
 
   # Do the actual comparison of two builds
--- a/make/autoconf/flags.m4	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/autoconf/flags.m4	Mon Feb 19 04:50:50 2018 +0100
@@ -175,6 +175,16 @@
         $1SYSROOT_CFLAGS="-I-xbuiltin -I[$]$1SYSROOT/usr/include"
         $1SYSROOT_LDFLAGS="-L[$]$1SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \
             -L[$]$1SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR"
+        # If the devkit contains the ld linker, make sure we use it.
+        AC_PATH_PROG(SOLARIS_LD, ld, , $DEVKIT_TOOLCHAIN_PATH:$DEVKIT_EXTRA_PATH)
+        # Make sure this ld is runnable.
+        if test -f "$SOLARIS_LD"; then
+          if "$SOLARIS_LD" -V > /dev/null 2> /dev/null; then
+            $1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS -Yl,$(dirname $SOLARIS_LD)"
+          else
+            AC_MSG_WARN([Could not run $SOLARIS_LD found in devkit, reverting to system ld])
+          fi
+        fi
       fi
     elif test "x$TOOLCHAIN_TYPE" = xgcc; then
       $1SYSROOT_CFLAGS="--sysroot=[$]$1SYSROOT"
--- a/make/conf/jib-profiles.js	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/conf/jib-profiles.js	Mon Feb 19 04:50:50 2018 +0100
@@ -768,7 +768,7 @@
         linux_x64: "gcc4.9.2-OEL6.4+1.2",
         macosx_x64: "Xcode6.3-MacOSX10.9+1.0",
         solaris_x64: "SS12u4-Solaris11u1+1.0",
-        solaris_sparcv9: "SS12u4-Solaris11u1+1.0",
+        solaris_sparcv9: "SS12u4-Solaris11u1+1.1",
         windows_x64: "VS2013SP4+1.0",
         linux_aarch64: "gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux+1.0",
         linux_arm: (input.profile != null && input.profile.indexOf("hflt") >= 0
--- a/make/devkit/createSolarisDevkit.sh	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/devkit/createSolarisDevkit.sh	Mon Feb 19 04:50:50 2018 +0100
@@ -73,7 +73,8 @@
 DEVKIT_ROOT=${BUILD_DIR}/${DEVKIT_NAME}
 BUNDLE_NAME=${DEVKIT_NAME}.tar.gz
 BUNDLE=${BUILD_DIR}/${BUNDLE_NAME}
-INSTALL_ROOT=${BUILD_DIR}/install-root
+INSTALL_ROOT=${BUILD_DIR}/install-root-$SOLARIS_VERSION
+INSTALL_ROOT_TOOLS=${BUILD_DIR}/install-root-tools-$SOLARIS_VERSION
 SYSROOT=${DEVKIT_ROOT}/sysroot
 SOLARIS_STUDIO_SUBDIR=SS${SOLARIS_STUDIO_VERSION}
 SOLARIS_STUDIO_DIR=${DEVKIT_ROOT}/${SOLARIS_STUDIO_SUBDIR}
@@ -92,17 +93,27 @@
   echo "Skipping installing packages"
 fi
 
+# Since we have implicitly been running 11.2 tools for a long time, we need
+# to pick them for the tools dir in the devkit. Create a separate install-root
+# for it.
+if [ ! -d $INSTALL_ROOT_TOOLS ]; then
+  echo "Creating $INSTALL_ROOT_TOOLS and installing packages"
+  pkg image-create $INSTALL_ROOT_TOOLS
+  pkg -R $INSTALL_ROOT_TOOLS set-publisher -P -g ${PUBLISHER_URI} solaris
+  sudo pkg -R $INSTALL_ROOT_TOOLS install --accept \
+      entire@0.5.11-0.175.2.5.0.5.0 \
+      system/linker \
+      developer/base-developer-utilities \
+      developer/gnu-binutils
+else
+  echo "Skipping installing tools packages"
+fi
+
 if [ ! -d $SYSROOT ]; then
   echo "Copying from $INSTALL_ROOT to $SYSROOT"
   mkdir -p $SYSROOT
   cp -rH $INSTALL_ROOT/lib $SYSROOT/
-  mkdir $SYSROOT/usr $DEVKIT_ROOT/gnu
-  # Some of the tools in sysroot are needed in the OpenJDK build but cannot be
-  # run from their current location due to relative runtime paths in the
-  # binaries. Move the sysroot/usr/bin directory to the outer bin and have them
-  # be runnable from there to force them to link to the system libraries
-  cp -rH $INSTALL_ROOT/usr/bin $DEVKIT_ROOT
-  cp -rH $INSTALL_ROOT/usr/gnu/bin $DEVKIT_ROOT/gnu/
+  mkdir $SYSROOT/usr
   cp -rH $INSTALL_ROOT/usr/lib $SYSROOT/usr/
   cp -rH $INSTALL_ROOT/usr/include $SYSROOT/usr/
   pkg -R $INSTALL_ROOT list > $SYSROOT/pkg-list.txt
@@ -110,10 +121,36 @@
   echo "Skipping copying to $SYSROOT"
 fi
 
+if [ ! -d $DEVKIT_ROOT/tools ]; then
+  echo "Copying from $INSTALL_ROOT_TOOLS to $DEVKIT_ROOT/tools"
+  # Some of the tools in sysroot are needed in the OpenJDK build. We need
+  # to copy them into a tools dir, including their specific libraries.
+  mkdir -p $DEVKIT_ROOT/tools/usr/bin/sparcv9 $DEVKIT_ROOT/tools/lib/sparcv9 \
+      $DEVKIT_ROOT/tools/usr/gnu/bin
+  cp $INSTALL_ROOT_TOOLS/usr/bin/{ar,nm,strip,ld,ldd} \
+       $DEVKIT_ROOT/tools/usr/bin/
+  cp $INSTALL_ROOT_TOOLS/usr/bin/sparcv9/{ar,nm,strip,ld,ldd} \
+       $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+  cp $INSTALL_ROOT_TOOLS/usr/sbin/dtrace $DEVKIT_ROOT/tools/usr/bin/
+  cp $INSTALL_ROOT_TOOLS/usr/sbin/sparcv9/dtrace $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+  cp -rH $INSTALL_ROOT_TOOLS/usr/gnu/bin/* $DEVKIT_ROOT/tools/usr/gnu/bin/
+  cp $INSTALL_ROOT_TOOLS/lib/{libelf.so*,libld.so*,liblddbg.so*} \
+      $DEVKIT_ROOT/tools/lib/
+  cp $INSTALL_ROOT_TOOLS/lib/sparcv9/{libelf.so*,libld.so*,liblddbg.so*} \
+      $DEVKIT_ROOT/tools/lib/sparcv9/
+  for t in $(ls $DEVKIT_ROOT/tools/usr/gnu/bin); do
+    if [ -f $DEVKIT_ROOT/tools/usr/gnu/bin/$t ]; then
+      ln -s ../gnu/bin/$t $DEVKIT_ROOT/tools/usr/bin/g$t
+    fi
+  done
+else
+  echo "Skipping copying to tools dir $DEVKIT_ROOT/tools"
+fi
+
 if [ ! -d $SOLARIS_STUDIO_DIR ]; then
   echo "Copying Solaris Studio from $SOLARIS_STUDIO_SRC"
-  cp -rH $SOLARIS_STUDIO_SRC ${SOLARIS_STUDIO_DIR%/*}
-  mv ${SOLARIS_STUDIO_DIR%/*}/${SOLARIS_STUDIO_SRC##*/} $SOLARIS_STUDIO_DIR
+  mkdir -p ${SOLARIS_STUDIO_DIR}
+  cp -rH $SOLARIS_STUDIO_SRC/. ${SOLARIS_STUDIO_DIR}/
   # Solaris Studio 12.4 requires /lib/libmmheap.so.1 to run, but this lib is not
   # installed by default on all Solaris systems. Sneak it in from the sysroot to
   # make it run OOTB on more systems.
@@ -123,10 +160,9 @@
 fi
 
 echo "Copying gnu make to $DEVKIT_ROOT/bin"
-mkdir -p $DEVKIT_ROOT/bin
-cp $GNU_MAKE $DEVKIT_ROOT/bin/
-if [ ! -e $DEVKIT_ROOT/bin/gmake ]; then
-  ln -s make $DEVKIT_ROOT/bin/gmake
+cp $GNU_MAKE $DEVKIT_ROOT/tools/usr/bin/
+if [ ! -e $DEVKIT_ROOT/tools/usr/bin/gmake ]; then
+  ln -s make $DEVKIT_ROOT/tools/usr/bin/gmake
 fi
 
 # Create the devkit.info file
@@ -136,7 +172,7 @@
 echo "# This file describes to configure how to interpret the contents of this devkit" >> $INFO_FILE
 echo "DEVKIT_NAME=\"Solaris Studio $SOLARIS_STUDIO_VERSION - Solaris $SOLARIS_VERSION - $ARCH\"" >> $INFO_FILE
 echo "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/$SOLARIS_STUDIO_SUBDIR/bin:\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
-echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
+echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/tools/usr/bin\"" >> $INFO_FILE
 echo "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/sysroot\"" >> $INFO_FILE
 
 if [ ! -e $BUNDLE ]; then
--- a/make/launcher/Launcher-jdk.jcmd.gmk	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/launcher/Launcher-jdk.jcmd.gmk	Mon Feb 19 04:50:50 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -60,3 +60,6 @@
 $(eval $(call SetupBuildLauncher, jcmd, \
     MAIN_CLASS := sun.tools.jcmd.JCmd, \
 ))
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, launcher/Launcher-jdk.jcmd-post.gmk))
--- a/make/launcher/Launcher-jdk.jstatd.gmk	Mon Feb 19 09:46:10 2018 +0100
+++ b/make/launcher/Launcher-jdk.jstatd.gmk	Mon Feb 19 04:50:50 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -28,3 +28,6 @@
 $(eval $(call SetupBuildLauncher, jstatd, \
     MAIN_CLASS := sun.tools.jstatd.Jstatd, \
 ))
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, launcher/Launcher-jdk.jstatd-post.gmk))
--- a/src/java.base/share/classes/java/lang/Thread.java	Mon Feb 19 09:46:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Thread.java	Mon Feb 19 04:50:50 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -150,9 +150,6 @@
     private Thread         threadQ;
     private long           eetop;
 
-    /* Whether or not to single_step this thread. */
-    private boolean     single_step;
-
     /* Whether or not the thread is a daemon thread. */
     private boolean     daemon = false;
 
--- a/src/java.base/share/classes/java/lang/ref/Finalizer.java	Mon Feb 19 09:46:10 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java	Mon Feb 19 04:50:50 2018 +0100
@@ -36,18 +36,18 @@
                                                           class */
 
     private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
+
+    /** Head of doubly linked list of Finalizers awaiting finalization. */
     private static Finalizer unfinalized = null;
+
+    /** Lock guarding access to unfinalized list. */
     private static final Object lock = new Object();
 
-    private Finalizer
-        next = null,
-        prev = null;
+    private Finalizer next, prev;
 
-    private boolean hasBeenFinalized() {
-        return (next == this);
-    }
-
-    private void add() {
+    private Finalizer(Object finalizee) {
+        super(finalizee, queue);
+        // push onto unfinalized
         synchronized (lock) {
             if (unfinalized != null) {
                 this.next = unfinalized;
@@ -57,31 +57,6 @@
         }
     }
 
-    private void remove() {
-        synchronized (lock) {
-            if (unfinalized == this) {
-                if (this.next != null) {
-                    unfinalized = this.next;
-                } else {
-                    unfinalized = this.prev;
-                }
-            }
-            if (this.next != null) {
-                this.next.prev = this.prev;
-            }
-            if (this.prev != null) {
-                this.prev.next = this.next;
-            }
-            this.next = this;   /* Indicates that this has been finalized */
-            this.prev = this;
-        }
-    }
-
-    private Finalizer(Object finalizee) {
-        super(finalizee, queue);
-        add();
-    }
-
     static ReferenceQueue<Object> getQueue() {
         return queue;
     }
@@ -91,11 +66,24 @@
         new Finalizer(finalizee);
     }
 
+    private void deregisterAndRunFinalizer(JavaLangAccess jla) {
+        synchronized (lock) {
+            if (this.next == this)      // already finalized
+                return;
+            // unlink from unfinalized
+            if (unfinalized == this)
+                unfinalized = this.next;
+            else
+                this.prev.next = this.next;
+            if (this.next != null)
+                this.next.prev = this.prev;
+            this.prev = null;
+            this.next = this;           // mark as finalized
+        }
+        runFinalizer(jla);
+    }
+
     private void runFinalizer(JavaLangAccess jla) {
-        synchronized (this) {
-            if (hasBeenFinalized()) return;
-            remove();
-        }
         try {
             Object finalizee = this.get();
             if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
@@ -155,11 +143,8 @@
                     return;
                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
                 running = true;
-                for (;;) {
-                    Finalizer f = (Finalizer)queue.poll();
-                    if (f == null) break;
-                    f.runFinalizer(jla);
-                }
+                for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
+                    f.deregisterAndRunFinalizer(jla);
             }
         });
     }
@@ -179,11 +164,15 @@
                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
                 running = true;
                 for (;;) {
+                    // "pollFirst" from unfinalized
                     Finalizer f;
                     synchronized (lock) {
                         f = unfinalized;
                         if (f == null) break;
                         unfinalized = f.next;
+                        if (unfinalized != null)
+                            unfinalized.prev = null;
+                        f.next = f; // mark as finalized
                     }
                     f.runFinalizer(jla);
                 }}});
@@ -214,7 +203,7 @@
             for (;;) {
                 try {
                     Finalizer f = (Finalizer)queue.remove();
-                    f.runFinalizer(jla);
+                    f.deregisterAndRunFinalizer(jla);
                 } catch (InterruptedException x) {
                     // ignore and continue
                 }
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Feb 19 09:46:10 2018 +0100
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Feb 19 04:50:50 2018 +0100
@@ -220,7 +220,7 @@
     Error: The JavaFX launchApplication method has the wrong signature, it\n\
     must be declared static and return a value of type void
 java.launcher.module.error1=\
-    module {0} does not have a MainClass attribute, use -m <module>/<main-class>
+    module {0} does not have a ModuleMainClass attribute, use -m <module>/<main-class>
 java.launcher.module.error2=\
     Error: Could not find or load main class {0} in module {1}
 java.launcher.module.error3=\
--- a/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java	Mon Feb 19 09:46:10 2018 +0100
+++ b/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java	Mon Feb 19 04:50:50 2018 +0100
@@ -77,7 +77,10 @@
 
     private void init(final ClassLoader loader) {
         globalScope = new SimpleBindings();
-        engineSpis = new TreeSet<ScriptEngineFactory>(Comparator.comparing(ScriptEngineFactory::getEngineName));
+        engineSpis = new TreeSet<ScriptEngineFactory>(Comparator.comparing(
+            ScriptEngineFactory::getEngineName,
+            Comparator.nullsLast(Comparator.naturalOrder()))
+        );
         nameAssociations = new HashMap<String, ScriptEngineFactory>();
         extensionAssociations = new HashMap<String, ScriptEngineFactory>();
         mimeTypeAssociations = new HashMap<String, ScriptEngineFactory>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactory.java	Mon Feb 19 04:50:50 2018 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import javax.script.*;
+import java.util.*;
+
+// do many bad things to prevent ScriptEngineManager to run correctly
+public class BadFactory implements ScriptEngineFactory {
+    public String getEngineName() {
+        return null;
+    }
+
+    public String getEngineVersion() {
+        return null;
+    }
+
+    public List<String> getExtensions() {
+        return null;
+    }
+
+    public String getLanguageName() {
+        return null;
+    }
+
+    public String getLanguageVersion() {
+        return null;
+    }
+
+    public String getMethodCallSyntax(String obj, String m, String[] args) {
+        return null;
+    }
+
+    public List<String> getMimeTypes() {
+        List<String> list = new ArrayList<String>();
+        list.add("application/bad");
+        list.add(null);
+        list.add("");
+        return list;
+    }
+
+    public List<String> getNames() {
+        throw new IllegalArgumentException();
+    }
+
+    public String getOutputStatement(String str) {
+        return "bad-factory-output";
+    }
+
+    public String getParameter(String key) {
+        return null;
+    }
+
+    public String getProgram(String[] statements) {
+        return null;
+    }
+
+    public ScriptEngine getScriptEngine() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.java	Mon Feb 19 04:50:50 2018 +0100
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 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.
+ */
+
+import javax.script.ScriptEngineManager;
+
+public class BadFactoryTest {
+    public static void main(String[] args) {
+        ScriptEngineManager m = new ScriptEngineManager();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh	Mon Feb 19 04:50:50 2018 +0100
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 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 8196959
+# @summary BadFactory that results in NPE being thrown from ScriptEngineManager
+#
+# @build BadFactory BadFactoryTest
+# @run shell BadFactoryTest.sh
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+. ${TESTSRC}/../CommonSetup.sh
+
+echo "Creating JAR file ..."
+
+$JAR ${TESTTOOLVMOPTS} -cf ${TESTCLASSES}/badfactory.jar \
+    -C ${TESTCLASSES} BadFactory.class \
+    -C ${TESTCLASSES} BadFactoryTest.class \
+    -C "${TESTSRC}" META-INF/services/javax.script.ScriptEngineFactory
+
+echo "Running test with security manager ..."
+$JAVA ${TESTVMOPTS} -Djava.security.manager -classpath \
+  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \
+  BadFactoryTest
+
+ret=$?
+if [ $ret -ne 0 ]
+then
+  exit $ret
+fi
+
+echo "Running test without security manager ..."
+$JAVA ${TESTVMOPTS} -classpath \
+  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactoty.jar" \
+  BadFactoryTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/script/JDK_8196959/META-INF/services/javax.script.ScriptEngineFactory	Mon Feb 19 04:50:50 2018 +0100
@@ -0,0 +1,2 @@
+# Factory that does many bad things to stress ScriptEngineManager
+BadFactory