Merge
authorlana
Fri, 02 Sep 2016 02:41:56 +0000
changeset 40756 ac2a115938ab
parent 40751 587d61cacb36 (current diff)
parent 40755 26f6264ee481 (diff)
child 40757 c1abf2140414
Merge
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java	Fri Sep 02 02:41:56 2016 +0000
@@ -31,6 +31,7 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -72,9 +73,6 @@
     //System Id for this catalog
     String systemId;
 
-    //The parent
-    CatalogImpl parent = null;
-
     /*
      A list of catalog entry files from the input, excluding the current catalog.
      Paths in the List are normalized.
@@ -107,7 +105,7 @@
      * catalog file.
      */
     public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException {
-        super(CatalogEntryType.CATALOG);
+        super(CatalogEntryType.CATALOG, parent);
         if (f == null) {
             throw new NullPointerException(
                     formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"}));
@@ -117,7 +115,7 @@
             CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]);
         }
 
-        init(parent, f);
+        init(f);
 
         //Path of catalog files
         String[] catalogFile = file;
@@ -159,19 +157,34 @@
                     }
                 }
             }
-
-            if (systemId != null) {
-                parse(systemId);
-            }
         }
     }
 
-    private void init(CatalogImpl parent, CatalogFeatures f) {
-        this.parent = parent;
+    /**
+     * Loads the catalog
+     */
+    void load() {
+        if (systemId != null) {
+            parse(systemId);
+        }
+
+        //save this catalog before loading the next
+        loadedCatalogs.put(systemId, this);
+
+        //Load delegate and alternative catalogs if defer is false.
+        if (!isDeferred()) {
+           loadDelegateCatalogs();
+           loadNextCatalogs();
+        }
+    }
+
+    private void init(CatalogFeatures f) {
         if (parent == null) {
             level = 0;
         } else {
             level = parent.level + 1;
+            this.loadedCatalogs = parent.loadedCatalogs;
+            this.catalogsSearched = parent.catalogsSearched;
         }
         if (f == null) {
             this.features = CatalogFeatures.defaults();
@@ -196,11 +209,6 @@
         entries.stream().filter((entry) -> (entry.type == CatalogEntryType.GROUP)).forEach((entry) -> {
             ((GroupEntry) entry).reset();
         });
-
-        if (parent != null) {
-            this.loadedCatalogs = parent.loadedCatalogs;
-            this.catalogsSearched = parent.catalogsSearched;
-        }
     }
 
     /**
@@ -421,16 +429,16 @@
     void loadNextCatalogs() {
         //loads catalogs specified in nextCatalogs
         if (nextCatalogs != null) {
-            for (NextCatalog next : nextCatalogs) {
+            nextCatalogs.stream().forEach((next) -> {
                 getCatalog(next.getCatalogURI());
-            }
+            });
         }
 
         //loads catalogs from the input list
         if (inputFiles != null) {
-            for (String file : inputFiles) {
+            inputFiles.stream().forEach((file) -> {
                 getCatalog(getSystemId(file));
-            }
+            });
         }
     }
 
@@ -445,14 +453,14 @@
             return null;
         }
 
-        Catalog c = null;
+        CatalogImpl c = null;
         String path = uri.toASCIIString();
 
         if (verifyCatalogFile(uri)) {
             c = getLoadedCatalog(path);
             if (c == null) {
                 c = new CatalogImpl(this, features, path);
-                saveLoadedCatalog(path, c);
+                c.load();
             }
         }
         return c;
@@ -464,7 +472,7 @@
      * @param catalogId the catalogId associated with the Catalog object
      * @param c the Catalog to be saved
      */
-    void saveLoadedCatalog(String catalogId, Catalog c) {
+    void saveLoadedCatalog(String catalogId, CatalogImpl c) {
         loadedCatalogs.put(catalogId, c);
     }
 
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java	Fri Sep 02 02:41:56 2016 +0000
@@ -62,7 +62,9 @@
      * @throws CatalogException If an error occurs while parsing the catalog
      */
     public static Catalog catalog(CatalogFeatures features, String... paths) {
-        return new CatalogImpl(features, paths);
+        CatalogImpl catalog = new CatalogImpl(features, paths);
+        catalog.load();
+        return catalog;
     }
 
     /**
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java	Fri Sep 02 02:41:56 2016 +0000
@@ -259,15 +259,6 @@
         CatalogEntryType type = CatalogEntryType.getType(localName);
         if (type == CatalogEntryType.GROUP) {
             inGroup = false;
-        } else if (type == CatalogEntryType.CATALOGENTRY) {
-            /*
-             Done reading the catalog file.
-             Load delegate and alternative catalogs if defer is false.
-             */
-            if (!catalog.isDeferred()) {
-                catalog.loadDelegateCatalogs();
-                catalog.loadNextCatalogs();
-            }
         }
     }
 
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java	Fri Sep 02 02:41:56 2016 +0000
@@ -119,6 +119,10 @@
         String result = null;
         CatalogImpl c = (CatalogImpl)catalog;
         String uri = Normalizer.normalizeURI(href);
+        if (uri == null) {
+            return null;
+        }
+
         //check whether uri is an urn
         if (uri != null && uri.startsWith(Util.URN)) {
             String publicId = Normalizer.decodeURN(uri);
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java	Fri Sep 02 02:41:56 2016 +0000
@@ -48,6 +48,9 @@
     //Value of the prefer attribute
     boolean isPreferPublic = true;
 
+    //The parent of the catalog instance
+    CatalogImpl parent = null;
+
     //The catalog instance this group belongs to
     CatalogImpl catalog;
 
@@ -55,10 +58,10 @@
     List<BaseEntry> entries = new ArrayList<>();
 
     //loaded delegated catalog by system id
-    Map<String, Catalog> delegateCatalogs = new HashMap<>();
+    Map<String, CatalogImpl> delegateCatalogs = new HashMap<>();
 
     //A list of all loaded Catalogs, including this, and next catalogs
-    Map<String, Catalog> loadedCatalogs = new HashMap<>();
+    Map<String, CatalogImpl> loadedCatalogs = new HashMap<>();
 
     /*
      A list of Catalog Ids that have already been searched in a matching
@@ -136,8 +139,9 @@
      *
      * @param type The type of the entry
      */
-    public GroupEntry(CatalogEntryType type) {
+    public GroupEntry(CatalogEntryType type, CatalogImpl parent) {
         super(type);
+        this.parent = parent;
     }
 
     /**
@@ -163,7 +167,7 @@
     }
     /**
      * Constructs a group entry.
-     * @param catalog The parent catalog
+     * @param catalog The catalog this GroupEntry belongs
      * @param base The baseURI attribute
      * @param attributes The attributes
      */
@@ -445,13 +449,14 @@
      * @param catalogId the catalog Id
      */
     Catalog loadCatalog(URI catalogURI) {
-        Catalog delegateCatalog = null;
+        CatalogImpl delegateCatalog = null;
         if (catalogURI != null) {
             String catalogId = catalogURI.toASCIIString();
             delegateCatalog = getLoadedCatalog(catalogId);
             if (delegateCatalog == null) {
                 if (verifyCatalogFile(catalogURI)) {
                     delegateCatalog = new CatalogImpl(catalog, features, catalogId);
+                    delegateCatalog.load();
                     delegateCatalogs.put(catalogId, delegateCatalog);
                 }
             }
@@ -467,8 +472,8 @@
      * @return a Catalog object previously loaded, or null if none in the saved
      * list
      */
-    Catalog getLoadedCatalog(String catalogId) {
-        Catalog c = null;
+    CatalogImpl getLoadedCatalog(String catalogId) {
+        CatalogImpl c = null;
 
         //checl delegate Catalogs
         c = delegateCatalogs.get(catalogId);
@@ -504,7 +509,7 @@
         }
 
         String catalogId = catalogURI.toASCIIString();
-        if (catalogsSearched.contains(catalogId)) {
+        if (catalogsSearched.contains(catalogId) || isCircular(catalogId)) {
             CatalogMessages.reportRunTimeError(CatalogMessages.ERR_CIRCULAR_REFERENCE,
                     new Object[]{CatalogMessages.sanitize(catalogId)});
         }
@@ -512,4 +517,20 @@
         return true;
     }
 
+    /**
+     * Checks whether the catalog is circularly referenced
+     * @param systemId the system identifier of the catalog to be loaded
+     * @return true if is circular, false otherwise
+     */
+    boolean isCircular(String systemId) {
+        if (parent == null) {
+            return false;
+        }
+
+        if (parent.systemId.equals(systemId)) {
+            return true;
+        }
+
+        return parent.isCircular(systemId);
+    }
 }
--- a/jaxp/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java	Fri Sep 02 02:41:56 2016 +0000
@@ -42,6 +42,9 @@
             ORACLE_JAXP_PROPERTY_PREFIX + "enableExtensionFunctions";
     public static final String SP_ENABLE_EXTENSION_FUNCTION =
             "javax.xml.enableExtensionFunctions";
+    // This is the correct name by the spec
+    public static final String SP_ENABLE_EXTENSION_FUNCTION_SPEC =
+            "jdk.xml.enableExtensionFunctions";
     public static final String CATALOG_FEATURES = "javax.xml.catalog.catalogFeatures";
 
     public final static String PROPERTY_USE_CATALOG = XMLConstants.USE_CATALOG;
@@ -49,11 +52,11 @@
     public static enum XmlFeature {
         /**
          * Feature enableExtensionFunctions
-         * FSP: extension function is enforced by FSP. When FSP is on, entension
+         * FSP: extension function is enforced by FSP. When FSP is on, extension
          * function is disabled.
          */
         ENABLE_EXTENSION_FUNCTION(ORACLE_ENABLE_EXTENSION_FUNCTION,
-                SP_ENABLE_EXTENSION_FUNCTION, true, false, true, true),
+                SP_ENABLE_EXTENSION_FUNCTION_SPEC, true, false, true, true),
         /**
          * The {@link javax.xml.XMLConstants.USE_CATALOG} feature.
          * FSP: USE_CATALOG is not enforced by FSP.
@@ -149,6 +152,30 @@
     }
 
     /**
+     * Maps old property names with the new ones. This map is used to keep track of
+     * name changes so that old or incorrect names continue to be supported for compatibility.
+     */
+    public static enum NameMap {
+
+        ENABLE_EXTENSION_FUNCTION(SP_ENABLE_EXTENSION_FUNCTION_SPEC, SP_ENABLE_EXTENSION_FUNCTION);
+
+        final String newName;
+        final String oldName;
+
+        NameMap(String newName, String oldName) {
+            this.newName = newName;
+            this.oldName = oldName;
+        }
+
+        String getOldName(String newName) {
+            if (newName.equals(this.newName)) {
+                return oldName;
+            }
+            return null;
+        }
+    }
+
+    /**
      * States of the settings of a property, in the order: default value, value
      * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system
      * properties, and jaxp api properties
@@ -316,6 +343,15 @@
     private void readSystemProperties() {
         for (XmlFeature feature : XmlFeature.values()) {
             getSystemProperty(feature, feature.systemProperty());
+            if (!getSystemProperty(feature, feature.systemProperty())) {
+                //if system property is not found, try the older form if any
+                for (NameMap nameMap : NameMap.values()) {
+                    String oldName = nameMap.getOldName(feature.systemProperty());
+                    if (oldName != null) {
+                        getSystemProperty(feature, oldName);
+                    }
+                }
+            }
         }
     }
 
--- a/jaxp/test/ProblemList.txt	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/ProblemList.txt	Fri Sep 02 02:41:56 2016 +0000
@@ -24,7 +24,3 @@
 ###########################################################################
 
 javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.sh            8147431 generic-all
-
-javax/xml/jaxp/unittest/common/TransformationWarningsTest.java	8150145 generic-all
-
-javax/xml/jaxp/unittest/common/ValidationWarningsTest.java      8150145 generic-all
--- a/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -64,12 +64,12 @@
     public Object[][] data() {
         return new Object[][]{
             // By default, alternative catalogs are not loaded.
-            {createCatalog(CatalogFeatures.defaults()), 0},
+            {createCatalog(CatalogFeatures.defaults()), 1},
             // Alternative catalogs are not loaded when DEFER is set to true.
-            {createCatalog(createDeferFeature(DEFER_TRUE)), 0},
-            // The 3 alternative catalogs are not pre-loaded
+            {createCatalog(createDeferFeature(DEFER_TRUE)), 1},
+            // The 3 alternative catalogs are pre-loaded along with the parent
             //when DEFER is set to false.
-            {createCatalog(createDeferFeature(DEFER_FALSE)), 3}};
+            {createCatalog(createDeferFeature(DEFER_FALSE)), 4}};
     }
 
     private CatalogFeatures createDeferFeature(String defer) {
--- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -93,7 +93,7 @@
      */
     public void testWithOneProvider() throws Exception {
         int exitValue
-            = executeTestJava("-mp", MOD_DIR1.toString(),
+            = executeTestJava("--module-path", MOD_DIR1.toString(),
                               "-cp", CLASSES_DIR.toString(),
                               "Main", "xmlprovider1")
                 .outputTo(System.out)
@@ -108,7 +108,7 @@
      */
     public void testWithTwoProvider() throws Exception {
         int exitValue
-            = executeTestJava("-mp", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(),
+            = executeTestJava("--module-path", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(),
                               "-cp", CLASSES_DIR.toString(),
                               "Main", "xmlprovider1", "xmlprovider2")
                 .outputTo(System.out)
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -92,6 +92,34 @@
         super.setUp();
     }
 
+    /*
+     * @bug 8162431
+     * Verifies that circular references are caught and
+     * CatalogException is thrown.
+     */
+    @Test(dataProvider = "getFeatures", expectedExceptions = CatalogException.class)
+    public void testCircularRef(CatalogFeatures cf, String xml) {
+        CatalogResolver catalogResolver = CatalogManager.catalogResolver(
+                cf,
+                getClass().getResource(xml).getFile());
+        catalogResolver.resolve("anyuri", "");
+    }
+
+    /*
+       DataProvider: used to verify circular reference
+        Data columns: CatalogFeatures, catalog
+     */
+    @DataProvider(name = "getFeatures")
+    public Object[][] getFeatures() {
+
+        return new Object[][]{
+            {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
+                "catalogReferCircle-itself.xml"},
+            {CatalogFeatures.defaults(), "catalogReferCircle-itself.xml"},
+            {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
+                "catalogReferCircle-left.xml"},
+            {CatalogFeatures.defaults(), "catalogReferCircle-left.xml"},};
+    }
 
     /*
      * @bug 8163232
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-itself.xml	Fri Sep 02 02:41:56 2016 +0000
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+    <nextCatalog catalog="catalogReferCircle-itself.xml" />
+</catalog>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-left.xml	Fri Sep 02 02:41:56 2016 +0000
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+    <nextCatalog catalog="catalogReferCircle-right.xml" />
+</catalog>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/catalogReferCircle-right.xml	Fri Sep 02 02:41:56 2016 +0000
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+    <nextCatalog catalog="catalogReferCircle-left.xml" />
+</catalog>
+
--- a/jaxp/test/javax/xml/jaxp/unittest/common/TransformationWarningsTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/TransformationWarningsTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -42,12 +42,13 @@
  * @test
  * @bug 8144593
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @compile -XDignore.symbol.file TestSAXDriver.java
  * @run testng/othervm -DrunSecMngr=true common.TransformationWarningsTest
  * @run testng/othervm common.TransformationWarningsTest
  * @summary Check that warnings about unsupported properties from parsers
  * are suppressed during the transformation process.
  */
-@Listeners({jaxp.library.BasePolicy.class})
+@Listeners({jaxp.library.BasePolicy.class, jaxp.library.InternalAPIPolicy.class})
 public class TransformationWarningsTest extends WarningsTestBase {
 
     @BeforeClass
@@ -80,7 +81,12 @@
         Source xslsrc = new StreamSource(new StringReader(xsl));
 
         // Create factory and transformer
-        TransformerFactory tf = TransformerFactory.newInstance();
+        TransformerFactory tf;
+        // newTransformer() method doc states that different transformer
+        // factories can be used concurrently by different Threads.
+        synchronized (TransformerFactory.class) {
+            tf = TransformerFactory.newInstance();
+        }
         Transformer t = tf.newTransformer(xslsrc);
 
         // Set URI Resolver to return the newly constructed xml
--- a/jaxp/test/javax/xml/jaxp/unittest/common/ValidationWarningsTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/ValidationWarningsTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -46,6 +46,7 @@
  * @bug 8144593
  * @key intermittent
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @compile -XDignore.symbol.file TestSAXDriver.java
  * @run testng/othervm -DrunSecMngr=true common.ValidationWarningsTest
  * @run testng/othervm common.ValidationWarningsTest
  * @summary Check that warnings about unsupported properties from SAX
--- a/jaxp/test/javax/xml/jaxp/unittest/common/WarningsTestBase.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/WarningsTestBase.java	Fri Sep 02 02:41:56 2016 +0000
@@ -23,11 +23,15 @@
 
 package common;
 
+import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
+
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
+import java.lang.Thread.UncaughtExceptionHandler;
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -58,25 +62,27 @@
         PrintStream defStdErr = System.err;
         //Set new byte array stream as standard error stream
         ByteArrayOutputStream byteStream = new ByteArrayOutputStream(5000);
-        System.setErr(new PrintStream(byteStream));
+        runWithAllPerm(() -> System.setErr(new PrintStream(byteStream)));
         //Execute multiple TestWorker tasks
         for (int id = 0; id < THREADS_COUNT; id++) {
             EXECUTOR.execute(new TestWorker(id));
         }
         //Initiate shutdown of previously submitted task
-        EXECUTOR.shutdown();
+        runWithAllPerm(EXECUTOR::shutdown);
         //Wait for termination of submitted tasks
         if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
             //If not all tasks terminates during the time out force them to shutdown
-            EXECUTOR.shutdownNow();
+            runWithAllPerm(EXECUTOR::shutdownNow);
         }
         //Restore default standard error stream
-        System.setErr(defStdErr);
+        runWithAllPerm(() -> System.setErr(defStdErr));
         //Print tasks stderr output
         String errContent = byteStream.toString();
         System.out.println("Standard error output content:");
         System.out.println(errContent);
-        //Check tasks stderr output for quatity of warning messages
+        //Check if uncaught exceptions were observed by one or more threads
+        Assert.assertFalse(uncaughtExceptions);
+        //Check tasks stderr output for quantity of warning messages
         Assert.assertTrue(warningPrintedOnce(XMLConstants.ACCESS_EXTERNAL_DTD, errContent));
         Assert.assertTrue(warningPrintedOnce(ENT_EXP_PROPERTY, errContent));
         Assert.assertTrue(warningPrintedOnce(XMLConstants.FEATURE_SECURE_PROCESSING, errContent));
@@ -123,6 +129,25 @@
         }
     }
 
+    // Thread factory that handles uncaughtExceptions and prints them
+    // to stdout instead of stderr.
+    private static class TestThreadFactory implements ThreadFactory {
+
+        public Thread newThread(final Runnable r) {
+            Thread t = Executors.defaultThreadFactory().newThread(r);
+            t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+                @Override
+                public void uncaughtException(Thread t, Throwable thr) {
+                    thr.printStackTrace(System.out);
+                    uncaughtExceptions = true;
+                }
+            });
+            return t;
+        }
+    }
+
+    //Flag that indicates if one or more threads from thread pool caught unhandled exception
+    private static boolean uncaughtExceptions = false;
     //Entity expansion limit property name
     private static final String ENT_EXP_PROPERTY = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
     //Number of simultaneous test threads
@@ -130,7 +155,7 @@
     //Number of iterations per one thread
     private static final int ITERATIONS_PER_THREAD = 4;
     //Test thread pool
-    private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
-    //Cyclic barrier for threads startup synchronisation
+    private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(new TestThreadFactory());
+    //Cyclic barrier for threads startup synchronization
     private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
 }
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java	Thu Sep 01 23:20:11 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLTFunctionsTest.java	Fri Sep 02 02:41:56 2016 +0000
@@ -34,11 +34,16 @@
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
+import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
+import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
+import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
+import static jaxp.library.JAXPTestUtilities.setSystemProperty;
+import static jaxp.library.JAXPTestUtilities.getSystemProperty;
 
 /*
  * @test
@@ -49,10 +54,66 @@
  * @summary This class contains tests for XSLT functions.
  */
 
-//@Listeners({jaxp.library.BasePolicy.class}) //uncomment this line after 8161454 is resolved
+@Listeners({jaxp.library.BasePolicy.class})
 public class XSLTFunctionsTest {
 
     /**
+     * @bug 8161454
+     * Verifies that the new / correct name is supported, as is the old / incorrect
+     * one for compatibility
+     */
+    @Test
+    public void testNameChange() {
+
+        boolean feature;
+        TransformerFactory tf = TransformerFactory.newInstance();
+        feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
+        System.out.println("Default setting: " + feature);
+        // The default: true if no SecurityManager, false otherwise
+        Assert.assertTrue(feature == getDefault());
+
+        setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION, getDefaultOpposite());
+        tf = TransformerFactory.newInstance();
+        feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
+        System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION + ": " + feature);
+        clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION);
+        // old/incorrect name is still supported
+        Assert.assertTrue(feature != getDefault());
+
+        setSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC, getDefaultOpposite());
+        tf = TransformerFactory.newInstance();
+        feature = tf.getFeature(ORACLE_ENABLE_EXTENSION_FUNCTION);
+        System.out.println("After setting " + SP_ENABLE_EXTENSION_FUNCTION_SPEC + ": " + feature);
+        clearSystemProperty(SP_ENABLE_EXTENSION_FUNCTION_SPEC);
+        // new/correct name is effective
+        Assert.assertTrue(feature != getDefault());
+    }
+
+    final boolean isSecure;
+    {
+        String runSecMngr = getSystemProperty("runSecMngr");
+        isSecure = runSecMngr != null && runSecMngr.equals("true");
+    }
+
+    // The default: true if no SecurityManager, false otherwise
+    private boolean getDefault() {
+        if (isSecure) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    // Gets a String value that is opposite to the default value
+    private String getDefaultOpposite() {
+        if (isSecure) {
+            return "true";
+        } else {
+            return "false";
+        }
+    }
+
+    /**
      * @bug 8062518 8153082
      * Verifies that a reference to the DTM created by XSLT document function is
      * actually read from the DTM by an extension function.
@@ -72,7 +133,9 @@
 
         // Create factory and transformer
         TransformerFactory tf = TransformerFactory.newInstance();
-        tf.setFeature("http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions", true);
+        tf.setFeature(ORACLE_ENABLE_EXTENSION_FUNCTION, true);
+        tf.setAttribute(EXTENSION_CLASS_LOADER,
+                runWithAllPerm(() -> Thread.currentThread().getContextClassLoader()));
         Transformer t = tf.newTransformer( xslsrc );
         t.setErrorListener(tf.getErrorListener());
 
@@ -133,5 +196,16 @@
 
     static final String documentTesteExpectedResult = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                                                     + "<root>[Test:Doc][Test:External Doc]</root>";
+
+    public static final String ORACLE_JAXP_PROPERTY_PREFIX =
+        "http://www.oracle.com/xml/jaxp/properties/";
+    /**
+     * Feature enableExtensionFunctions
+     */
+    public static final String ORACLE_ENABLE_EXTENSION_FUNCTION =
+            ORACLE_JAXP_PROPERTY_PREFIX + "enableExtensionFunctions";
+    static final String SP_ENABLE_EXTENSION_FUNCTION = "javax.xml.enableExtensionFunctions";
+    // This is the correct name by the spec
+    static final String SP_ENABLE_EXTENSION_FUNCTION_SPEC = "jdk.xml.enableExtensionFunctions";
+    private static final String EXTENSION_CLASS_LOADER = "jdk.xml.transform.extensionClassLoader";
 }
-