diff --git a/jdk/make/docs/CORE_PKGS.gmk b/jdk/make/docs/CORE_PKGS.gmk index d55bb8b664e..1a5e7363048 100644 --- a/jdk/make/docs/CORE_PKGS.gmk +++ b/jdk/make/docs/CORE_PKGS.gmk @@ -142,6 +142,7 @@ CORE_PKGS = \ java.util.prefs \ java.util.regex \ java.util.spi \ + java.util.stream \ java.util.zip \ javax.accessibility \ javax.activation \ diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index 47184e3dd7b..1bdbdf03b31 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -252,6 +252,7 @@ JAVA_JAVA_java = \ java/util/Scanner.java \ java/util/InputMismatchException.java \ java/util/Stack.java \ + java/util/StringJoiner.java \ java/util/StringTokenizer.java \ java/util/TimeZone.java \ java/util/SimpleTimeZone.java \ diff --git a/jdk/make/netbeans/common/closed-share-sources.ent b/jdk/make/netbeans/common/closed-share-sources.ent index 91c6b9cadbf..03c7cda142e 100644 --- a/jdk/make/netbeans/common/closed-share-sources.ent +++ b/jdk/make/netbeans/common/closed-share-sources.ent @@ -37,6 +37,7 @@ ${root}/src/closed/share/classes ${includes} ${excludes} + US-ASCII diff --git a/jdk/make/netbeans/common/demo-view.ent b/jdk/make/netbeans/common/demo-view.ent index 5ae4e5abe84..43aa3141f57 100644 --- a/jdk/make/netbeans/common/demo-view.ent +++ b/jdk/make/netbeans/common/demo-view.ent @@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + ${root}/src/share/demo ${demos} diff --git a/jdk/make/netbeans/common/java-data-native.ent b/jdk/make/netbeans/common/java-data-native.ent index 8db2a86d618..54c7486aafb 100644 --- a/jdk/make/netbeans/common/java-data-native.ent +++ b/jdk/make/netbeans/common/java-data-native.ent @@ -1,7 +1,7 @@ - + ${root}/test ${jtreg.tests} diff --git a/jdk/make/netbeans/common/macosx-sources.ent b/jdk/make/netbeans/common/macosx-sources.ent new file mode 100644 index 00000000000..779ec604f63 --- /dev/null +++ b/jdk/make/netbeans/common/macosx-sources.ent @@ -0,0 +1,49 @@ + + + + + + + + java + ${root}/src/macosx/classes + ${includes} + ${excludes} + US-ASCII + + + + ${root}/src/macosx/classes + diff --git a/jdk/make/netbeans/common/macosx-view.ent b/jdk/make/netbeans/common/macosx-view.ent new file mode 100644 index 00000000000..8696adb6e25 --- /dev/null +++ b/jdk/make/netbeans/common/macosx-view.ent @@ -0,0 +1,43 @@ + + + + + + + + ${root}/src/macosx/classes + ${includes} + ${excludes} + diff --git a/jdk/make/netbeans/common/properties.ent b/jdk/make/netbeans/common/properties.ent index 482ea1a727b..dbf304e8d86 100644 --- a/jdk/make/netbeans/common/properties.ent +++ b/jdk/make/netbeans/common/properties.ent @@ -41,3 +41,5 @@ ${user.home}/.openjdk/build.properties build.properties ${java.home}/.. +${env.JT_HOME} +** diff --git a/jdk/make/netbeans/common/sample-view.ent b/jdk/make/netbeans/common/sample-view.ent index 5326f48122e..c2f63479901 100644 --- a/jdk/make/netbeans/common/sample-view.ent +++ b/jdk/make/netbeans/common/sample-view.ent @@ -1,7 +1,7 @@ - + ${root}/src/share/sample ${samples} diff --git a/jdk/make/netbeans/common/share-sources.ent b/jdk/make/netbeans/common/share-sources.ent index efa90bacd0b..3d995a4489d 100644 --- a/jdk/make/netbeans/common/share-sources.ent +++ b/jdk/make/netbeans/common/share-sources.ent @@ -37,6 +37,7 @@ ${root}/src/share/classes ${includes} ${excludes} + US-ASCII diff --git a/jdk/make/netbeans/common/shared.xml b/jdk/make/netbeans/common/shared.xml index ba104445273..36d57de7c43 100644 --- a/jdk/make/netbeans/common/shared.xml +++ b/jdk/make/netbeans/common/shared.xml @@ -276,7 +276,7 @@ - + @@ -338,7 +338,7 @@ - diff --git a/jdk/make/netbeans/common/unix-sources.ent b/jdk/make/netbeans/common/unix-sources.ent index da3980b0835..0c55fe34642 100644 --- a/jdk/make/netbeans/common/unix-sources.ent +++ b/jdk/make/netbeans/common/unix-sources.ent @@ -41,6 +41,7 @@ ${root}/src/solaris/classes ${includes} ${excludes} + US-ASCII diff --git a/jdk/make/netbeans/common/windows-sources.ent b/jdk/make/netbeans/common/windows-sources.ent index d50a91b45b7..6d5425a912d 100644 --- a/jdk/make/netbeans/common/windows-sources.ent +++ b/jdk/make/netbeans/common/windows-sources.ent @@ -37,6 +37,7 @@ ${root}/src/windows/classes ${includes} ${excludes} + US-ASCII diff --git a/jdk/make/netbeans/j2se/nbproject/project.xml b/jdk/make/netbeans/j2se/nbproject/project.xml index 784ab7232b8..dd15578f98a 100644 --- a/jdk/make/netbeans/j2se/nbproject/project.xml +++ b/jdk/make/netbeans/j2se/nbproject/project.xml @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/make/netbeans/jdbc/nbproject/project.xml b/jdk/make/netbeans/jdbc/nbproject/project.xml new file mode 100644 index 00000000000..af7e5580b69 --- /dev/null +++ b/jdk/make/netbeans/jdbc/nbproject/project.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + +]> + + org.netbeans.modules.ant.freeform + + + JDBC + + jdbc + &properties; + + + &share-sources; + &jtreg-sources; + &build-folder; + + + &standard-bindings; + + run + + + debug + + + debug + + + + + &share-view; + &jtreg-view; + &file-view; + + + &standard-actions; + + + + + + + &java-data-no-native; + + diff --git a/jdk/make/netbeans/world/nbproject/project.xml b/jdk/make/netbeans/world/nbproject/project.xml index 8c9ad4508d1..7f2f437905e 100644 --- a/jdk/make/netbeans/world/nbproject/project.xml +++ b/jdk/make/netbeans/world/nbproject/project.xml @@ -1,7 +1,7 @@ "); + assertEquals(sj.length(), 4); + assertEquals(sj.toString().length(), sj.length()); + sj.add("abcdef"); + assertEquals(sj.length(), 10); + assertEquals(sj.toString().length(), sj.length()); + sj.add("xyz"); + assertEquals(sj.length(), 15); + assertEquals(sj.toString().length(), sj.length()); + } + + public void noAddAndEmptyValue() { + StringJoiner sj = new StringJoiner(DASH, "", "").setEmptyValue(EMPTY); + assertEquals(sj.toString(), EMPTY); + + sj = new StringJoiner(DASH, "<..", ""); + assertEquals(sj.toString(), "<.."); + + sj = new StringJoiner(DASH, "<..", ""); + assertEquals(sj.toString(), "<.."); + + sj = new StringJoiner(DASH, "", "==>"); + assertEquals(sj.toString(), "==>"); + + sj = new StringJoiner(DASH, "{", "}"); + assertEquals(sj.toString(), "{}"); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void setEmptyValueNull() { + new StringJoiner(DASH, "{", "}").setEmptyValue(null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void setDelimiterNull() { + new StringJoiner(null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void setPrefixNull() { + new StringJoiner(DASH, null, "}"); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void setSuffixNull() { + new StringJoiner(DASH, "{", null); + } + + public void stringFromtoString() { + StringJoiner sj = new StringJoiner(", "); + assertEquals(sj.toString(), ""); + sj = new StringJoiner(",", "{", "}"); + assertEquals(sj.toString(), "{}"); + + sj = new StringJoiner(","); + sj.add(ONE); + assertEquals(sj.toString(), ONE); + + sj.add(TWO); + assertEquals(sj.toString(), ONE + "," + TWO); + + sj = new StringJoiner(",", "{--", "--}"); + sj.add(ONE); + sj.add(TWO); + assertEquals(sj.toString(), "{--" + ONE + "," + TWO + "--}"); + + } + + public void stringFromtoStringWithEmptyValue() { + StringJoiner sj = new StringJoiner(" ", "", ""); + assertEquals(sj.toString(), ""); + sj = new StringJoiner(", "); + assertEquals(sj.toString(), ""); + sj = new StringJoiner(",", "{", "}"); + assertEquals(sj.toString(), "{}"); + + sj = new StringJoiner(",", "{", "}").setEmptyValue(""); + assertEquals(sj.toString(), ""); + + sj = new StringJoiner(","); + sj.add(ONE); + assertEquals(sj.toString(), ONE); + + sj.add(TWO); + assertEquals(sj.toString(), ONE + "," + TWO); + + sj = new StringJoiner(",", "{--", "--}"); + sj.add(ONE); + assertEquals(sj.toString(), "{--" + ONE + "--}" ); + + sj.add(TWO); + assertEquals(sj.toString(), "{--" + ONE + "," + TWO + "--}"); + + } + + public void toStringWithCustomEmptyValue() { + StringJoiner sj = new StringJoiner(DASH, "<", ">").setEmptyValue(EMPTY); + assertEquals(sj.toString(), EMPTY); + sj.add(""); + assertEquals(sj.toString(), "<>"); + sj.add(""); + assertEquals(sj.toString(), "<->"); + } + + private void testCombos(String infix, String prefix, String suffix) { + StringJoiner sj = new StringJoiner(infix, prefix, suffix); + assertEquals(sj.toString(), prefix + suffix); + assertEquals(sj.toString().length(), sj.length()); + // EmptyValue + sj = new StringJoiner(infix, prefix, suffix).setEmptyValue(""); + assertEquals(sj.toString(), ""); + assertEquals(sj.toString().length(), sj.length()); + + // empty in front + sj.add(""); + assertEquals(sj.toString(), prefix + suffix); + // empty in middle + sj.add(""); + assertEquals(sj.toString(), prefix + infix + suffix); + sj.add("1"); + assertEquals(sj.toString(), prefix + infix + infix + "1" + suffix); + // empty at end + sj.add(""); + assertEquals(sj.toString(), prefix + infix + infix + "1" + infix + suffix); + + sj = new StringJoiner(infix, prefix, suffix).setEmptyValue(""); + sj.add("1"); + assertEquals(sj.toString(), prefix + "1" + suffix); + sj.add("2"); + assertEquals(sj.toString(), prefix + "1" + infix + "2" + suffix); + sj.add(""); + assertEquals(sj.toString(), prefix + "1" + infix + "2" +infix + suffix); + sj.add("3"); + assertEquals(sj.toString(), prefix + "1" + infix + "2" +infix + infix + "3" + suffix); + } + + public void testDelimiterCombinations() { + testCombos("", "", ""); + testCombos("", "<", ""); + testCombos("", "", ">"); + testCombos("", "<", ">"); + testCombos(",", "", ""); + testCombos(",", "<", ""); + testCombos(",", "", ">"); + testCombos(",", "<", ">"); + } +} + diff --git a/jdk/test/java/util/logging/DrainFindDeadlockTest.java b/jdk/test/java/util/logging/DrainFindDeadlockTest.java new file mode 100644 index 00000000000..13a959c07ff --- /dev/null +++ b/jdk/test/java/util/logging/DrainFindDeadlockTest.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.lang.Thread.State; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.util.logging.LogManager; +import java.util.logging.Logger; +import java.util.Map; + +/** + * @test + * @bug 8010939 + * @summary check for deadlock between findLogger() and drainLoggerRefQueueBounded() + * @author jim.gish@oracle.com + * @build DrainFindDeadlockTest + * @run main/othervm/timeout=10 DrainFindDeadlockTest + */ + +/** + * This test is checking for a deadlock between + * LogManager$LoggerContext.findLogger() and + * LogManager.drainLoggerRefQueueBounded() (which could happen by calling + * Logger.getLogger() and LogManager.readConfiguration() in different threads) + */ +public class DrainFindDeadlockTest { + private LogManager mgr = LogManager.getLogManager(); + private final static int MAX_ITERATIONS = 100; + + // Get a ThreadMXBean so we can check for deadlock. N.B. this may + // not be supported on all platforms, which means we will have to + // resort to the traditional test timeout method. However, if + // we have the support we'll get the deadlock details if one + // is detected. + private final static ThreadMXBean threadMXBean = + ManagementFactory.getThreadMXBean(); + private final boolean threadMXBeanDeadlockSupported = + threadMXBean.isSynchronizerUsageSupported(); + + public static void main(String... args) throws IOException, Exception { + new DrainFindDeadlockTest().testForDeadlock(); + } + + public static void randomDelay() { + int runs = (int) Math.random() * 1000000; + int c = 0; + + for (int i=0; i threadMap = + Thread.getAllStackTraces(); + dumpStack(threadMap.get(x), x); + dumpStack(threadMap.get(y), y); + } + } + + private void dumpStack(StackTraceElement[] aStackElt, Thread aThread) { + if (aStackElt != null) { + System.out.println("Thread:" + aThread.getName() + ": " + + aThread.getState()); + for (StackTraceElement element: aStackElt) { + System.out.println(" " + element); + } + } + } + + @Override + public void run() { + System.out.println("Running " + Thread.currentThread().getName()); + for (int i=0; i < MAX_ITERATIONS*2; i++) { + checkState(t1, t2); + try { + Thread.sleep(10); + } catch (InterruptedException ex) { + }; + } + } + } +} diff --git a/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties b/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties new file mode 100644 index 00000000000..71848703ed2 --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/ClassPathTestBundle_en.properties @@ -0,0 +1,25 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +sample1=translation #2 for sample1 +sample2=translation #2 for sample2 +supports-test=ResourceBundleSearchTest diff --git a/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java new file mode 100644 index 00000000000..76dc1232f22 --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/IndirectlyLoadABundle.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; + +/** + * This class is used to ensure that a resource bundle loadable by a classloader + * is on the caller's stack, but not on the classpath or TCCL to ensure that + * Logger.getLogger() can't load the bundle via a stack search + * + * @author Jim Gish + */ +public class IndirectlyLoadABundle { + + private final static String rbName = "StackSearchableResource"; + + public boolean loadAndTest() throws Throwable { + // Find out where we are running from so we can setup the URLClassLoader URLs + // test.src and test.classes will be set if running in jtreg, but probably + // not otherwise + String testDir = System.getProperty("test.src", System.getProperty("user.dir")); + String testClassesDir = System.getProperty("test.classes", + System.getProperty("user.dir")); + String sep = System.getProperty("file.separator"); + + URL[] urls = new URL[2]; + + // Allow for both jtreg and standalone cases here + urls[0] = Paths.get(testDir, "resources").toUri().toURL(); + urls[1] = Paths.get(testClassesDir).toUri().toURL(); + + System.out.println("INFO: urls[0] = " + urls[0]); + System.out.println("INFO: urls[1] = " + urls[1]); + + // Make sure we can find it via the URLClassLoader + URLClassLoader yetAnotherResourceCL = new URLClassLoader(urls, null); + if (!testForValidResourceSetup(yetAnotherResourceCL)) { + throw new Exception("Couldn't directly load bundle " + rbName + + " as expected. Test config problem"); + } + // But it shouldn't be available via the system classloader + ClassLoader myCL = this.getClass().getClassLoader(); + if (testForValidResourceSetup(myCL)) { + throw new Exception("Was able to directly load bundle " + rbName + + " from " + myCL + " but shouldn't have been" + + " able to. Test config problem"); + } + + Class loadItUpClazz = Class.forName("LoadItUp", true, yetAnotherResourceCL); + ClassLoader actual = loadItUpClazz.getClassLoader(); + if (actual != yetAnotherResourceCL) { + throw new Exception("LoadItUp was loaded by an unexpected CL: " + actual); + } + Object loadItUp = loadItUpClazz.newInstance(); + Method testMethod = loadItUpClazz.getMethod("test", String.class); + try { + return (Boolean) testMethod.invoke(loadItUp, rbName); + } catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + + private boolean testForValidResourceSetup(ClassLoader cl) { + // First make sure the test environment is setup properly and the bundle actually + // exists + return ResourceBundleSearchTest.isOnClassPath(rbName, cl); + } +} diff --git a/jdk/test/java/util/logging/bundlesearch/LoadItUp.java b/jdk/test/java/util/logging/bundlesearch/LoadItUp.java new file mode 100644 index 00000000000..d47b9a3e144 --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/LoadItUp.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.MissingResourceException; +import java.util.logging.Logger; + +/* + * This class is loaded onto the call stack when the test method is called + * and then its classloader can be used to find a property bundle in the same + * directory as the class. However, Logger is not allowed + * to find the bundle by looking up the stack for this classloader. + * We verify that this cannot happen. + * + * @author Jim Gish + */ +public class LoadItUp { + + private final static boolean DEBUG = false; + + public Boolean test(String rbName) throws Exception { + // we should not be able to find the resource in this directory via + // getLogger calls. The only way that would be possible given this setup + // is that if Logger.getLogger searched up the call stack + return lookupBundle(rbName); + } + + private boolean lookupBundle(String rbName) { + // See if Logger.getLogger can find the resource in this directory + try { + Logger aLogger = Logger.getLogger("NestedLogger", rbName); + } catch (MissingResourceException re) { + if (DEBUG) { + System.out.println( + "As expected, LoadItUp.lookupBundle() did not find the bundle " + + rbName); + } + return false; + } + System.out.println("FAILED: LoadItUp.lookupBundle() found the bundle " + + rbName + " using a stack search."); + return true; + } +} diff --git a/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java new file mode 100644 index 00000000000..00f1840042b --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/ResourceBundleSearchTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8002070 + * @summary Remove the stack search for a resource bundle Logger to use + * @author Jim Gish + * @build ResourceBundleSearchTest IndirectlyLoadABundle LoadItUp + * @run main ResourceBundleSearchTest + */ +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.logging.Logger; + +public class ResourceBundleSearchTest { + + private final static boolean DEBUG = false; + private final static String LOGGER_PREFIX = "myLogger."; + private static int loggerNum = 0; + private final static String PROP_RB_NAME = "ClassPathTestBundle"; + private final static String TCCL_TEST_BUNDLE = "ContextClassLoaderTestBundle"; + + private static int numPass = 0; + private static int numFail = 0; + private static List msgs = new ArrayList<>(); + + public static void main(String[] args) throws Throwable { + ResourceBundleSearchTest test = new ResourceBundleSearchTest(); + test.runTests(); + } + + private void runTests() throws Throwable { + // ensure we are using en as the default Locale so we can find the resource + Locale.setDefault(Locale.ENGLISH); + + String testClasses = System.getProperty("test.classes"); + System.out.println( "test.classes = " + testClasses ); + + ClassLoader myClassLoader = ClassLoader.getSystemClassLoader(); + + // Find out where we are running from so we can setup the URLClassLoader URL + String userDir = System.getProperty("user.dir"); + String testDir = System.getProperty("test.src", userDir); + String sep = System.getProperty("file.separator"); + + URL[] urls = new URL[1]; + + urls[0] = Paths.get(testDir, "resources").toUri().toURL(); + URLClassLoader rbClassLoader = new URLClassLoader(urls); + + // Test 1 - can we find a Logger bundle from doing a stack search? + // We shouldn't be able to + assertFalse(testGetBundleFromStackSearch(), "testGetBundleFromStackSearch"); + + // Test 2 - can we find a Logger bundle off of the Thread context class + // loader? We should be able to. + assertTrue( + testGetBundleFromTCCL(TCCL_TEST_BUNDLE, rbClassLoader), + "testGetBundleFromTCCL"); + + // Test 3 - Can we find a Logger bundle from the classpath? We should be + // able to, but .... + // We check to see if the bundle is on the classpath or not so that this + // will work standalone. In the case of jtreg/samevm, + // the resource bundles are not on the classpath. Running standalone + // (or othervm), they are + if (isOnClassPath(PROP_RB_NAME, myClassLoader)) { + debug("We should be able to see " + PROP_RB_NAME + " on the classpath"); + assertTrue(testGetBundleFromSystemClassLoader(PROP_RB_NAME), + "testGetBundleFromSystemClassLoader"); + } else { + debug("We should not be able to see " + PROP_RB_NAME + " on the classpath"); + assertFalse(testGetBundleFromSystemClassLoader(PROP_RB_NAME), + "testGetBundleFromSystemClassLoader"); + } + + report(); + } + + private void report() throws Exception { + System.out.println("Num passed = " + numPass + " Num failed = " + numFail); + if (numFail > 0) { + // We only care about the messages if they were errors + for (String msg : msgs) { + System.out.println(msg); + } + throw new Exception(numFail + " out of " + (numPass + numFail) + + " tests failed."); + } + } + + public void assertTrue(boolean testResult, String testName) { + if (testResult) { + numPass++; + } else { + numFail++; + System.out.println("FAILED: " + testName + + " was supposed to return true but did NOT!"); + } + } + + public void assertFalse(boolean testResult, String testName) { + if (!testResult) { + numPass++; + } else { + numFail++; + System.out.println("FAILED: " + testName + + " was supposed to return false but did NOT!"); + } + } + + public boolean testGetBundleFromStackSearch() throws Throwable { + // This should fail. This was the old functionality to search up the + // caller's call stack + IndirectlyLoadABundle indirectLoader = new IndirectlyLoadABundle(); + return indirectLoader.loadAndTest(); + } + + public boolean testGetBundleFromTCCL(String bundleName, + ClassLoader setOnTCCL) throws InterruptedException { + // This should succeed. We should be able to get the bundle from the + // thread context class loader + debug("Looking for " + bundleName + " using TCCL"); + LoggingThread lr = new LoggingThread(bundleName, setOnTCCL); + lr.start(); + synchronized (lr) { + try { + lr.wait(); + } catch (InterruptedException ex) { + throw ex; + } + } + msgs.add(lr.msg); + return lr.foundBundle; + } + + /* + * @param String bundleClass + * @param ClassLoader to use for search + * @return true iff bundleClass is on system classpath + */ + public static boolean isOnClassPath(String baseName, ClassLoader cl) { + ResourceBundle rb = null; + try { + rb = ResourceBundle.getBundle(baseName, Locale.getDefault(), cl); + System.out.println("INFO: Found bundle " + baseName + " on " + cl); + } catch (MissingResourceException e) { + System.out.println("INFO: Could not find bundle " + baseName + " on " + cl); + return false; + } + return (rb != null); + } + + private static String newLoggerName() { + // we need a new logger name every time we attempt to find a bundle via + // the Logger.getLogger call, so we'll simply tack on an integer which + // we increment each time this is called + loggerNum++; + return LOGGER_PREFIX + loggerNum; + } + + public boolean testGetBundleFromSystemClassLoader(String bundleName) { + // this should succeed if the bundle is on the system classpath. + try { + Logger aLogger = Logger.getLogger(ResourceBundleSearchTest.newLoggerName(), + bundleName); + } catch (MissingResourceException re) { + msgs.add("INFO: testGetBundleFromSystemClassLoader() did not find bundle " + + bundleName); + return false; + } + msgs.add("INFO: testGetBundleFromSystemClassLoader() found the bundle " + + bundleName); + return true; + } + + public static class LoggingThread extends Thread { + + boolean foundBundle = false; + String msg = null; + ClassLoader clToSetOnTCCL = null; + String bundleName = null; + + public LoggingThread(String bundleName) { + this.bundleName = bundleName; + } + + public LoggingThread(String bundleName, ClassLoader setOnTCCL) { + this.clToSetOnTCCL = setOnTCCL; + this.bundleName = bundleName; + } + + public void run() { + boolean setTCCL = false; + try { + if (clToSetOnTCCL != null) { + Thread.currentThread().setContextClassLoader(clToSetOnTCCL); + setTCCL = true; + } + // this should succeed if the bundle is on the system classpath. + try { + Logger aLogger = Logger.getLogger(ResourceBundleSearchTest.newLoggerName(), + bundleName); + msg = "INFO: LoggingRunnable() found the bundle " + bundleName + + (setTCCL ? " with " : " without ") + "setting the TCCL"; + foundBundle = true; + } catch (MissingResourceException re) { + msg = "INFO: LoggingRunnable() did not find the bundle " + bundleName + + (setTCCL ? " with " : " without ") + "setting the TCCL"; + foundBundle = false; + } + } catch (Throwable e) { + e.printStackTrace(); + System.exit(1); + } + } + } + + private void debug(String msg) { + if (DEBUG) { + System.out.println(msg); + } + } +} diff --git a/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties b/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties new file mode 100644 index 00000000000..ad4085ad164 --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/resources/ContextClassLoaderTestBundle_en.properties @@ -0,0 +1,25 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +sample1=translation #3 for sample1 +sample2=translation #3 for sample2 +supports-test=ResourceBundleSearchTest diff --git a/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties b/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties new file mode 100644 index 00000000000..17ba4437d90 --- /dev/null +++ b/jdk/test/java/util/logging/bundlesearch/resources/StackSearchableResource_en.properties @@ -0,0 +1,25 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +sample1=translation #4 for sample1 +sample2=translation #4 for sample2 +supports-test=ResourceBundleSearchTest diff --git a/jdk/test/java/util/regex/RegExTest.java b/jdk/test/java/util/regex/RegExTest.java index 3f8679ae976..bc345eda853 100644 --- a/jdk/test/java/util/regex/RegExTest.java +++ b/jdk/test/java/util/regex/RegExTest.java @@ -33,7 +33,7 @@ * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940 * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133 * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066 - * 7067045 7014640 7189363 + * 7067045 7014640 7189363 8007395 */ import java.util.regex.*; @@ -144,6 +144,7 @@ public class RegExTest { horizontalAndVerticalWSTest(); linebreakTest(); branchTest(); + groupCurlyNotFoundSuppTest(); if (failure) { throw new RuntimeException("RegExTest failed, 1st failure: " + @@ -3947,4 +3948,27 @@ public class RegExTest { report("branchTest"); } + // This test is for 8007395 + private static void groupCurlyNotFoundSuppTest() throws Exception { + String input = "test this as \ud83d\ude0d"; + for (String pStr : new String[] { "test(.)+(@[a-zA-Z.]+)", + "test(.)*(@[a-zA-Z.]+)", + "test([^B])+(@[a-zA-Z.]+)", + "test([^B])*(@[a-zA-Z.]+)", + "test(\\P{IsControl})+(@[a-zA-Z.]+)", + "test(\\P{IsControl})*(@[a-zA-Z.]+)", + }) { + Matcher m = Pattern.compile(pStr, Pattern.CASE_INSENSITIVE) + .matcher(input); + try { + if (m.find()) { + failCount++; + } + } catch (Exception x) { + failCount++; + } + } + report("GroupCurly NotFoundSupp"); + } + } diff --git a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java index 8dbb23503fc..135dfff0c40 100644 --- a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java +++ b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java @@ -46,10 +46,10 @@ import java.util.concurrent.FutureTask; * @bug 8010117 * @summary Verify if CallerSensitive methods are annotated with * sun.reflect.CallerSensitive annotation - * @build CallerSensitiveFinder MethodFinder + * @build CallerSensitiveFinder * @run main/othervm/timeout=900 -mx600m CallerSensitiveFinder */ -public class CallerSensitiveFinder extends MethodFinder { +public class CallerSensitiveFinder { private static int numThreads = 3; private static boolean verbose = false; public static void main(String[] args) throws Exception { @@ -71,8 +71,7 @@ public class CallerSensitiveFinder extends MethodFinder { if (classes.isEmpty()) { classes.addAll(PlatformClassPath.getJREClasses()); } - final String method = "sun/reflect/Reflection.getCallerClass"; - CallerSensitiveFinder csfinder = new CallerSensitiveFinder(method); + CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); if (!errors.isEmpty()) { @@ -82,8 +81,46 @@ public class CallerSensitiveFinder extends MethodFinder { } private final List csMethodsMissingAnnotation = new ArrayList<>(); - public CallerSensitiveFinder(String... methods) { - super(methods); + private final ReferenceFinder finder; + public CallerSensitiveFinder() { + this.finder = new ReferenceFinder(getFilter(), getVisitor()); + } + + private ReferenceFinder.Filter getFilter() { + final String classname = "sun/reflect/Reflection"; + final String method = "getCallerClass"; + return new ReferenceFinder.Filter() { + public boolean accept(ConstantPool cpool, CPRefInfo cpref) { + try { + CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo(); + return cpref.getClassName().equals(classname) && nat.getName().equals(method); + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + }; + } + + private ReferenceFinder.Visitor getVisitor() { + return new ReferenceFinder.Visitor() { + public void visit(ClassFile cf, Method m, List refs) { + try { + String name = String.format("%s#%s %s", cf.getName(), + m.getName(cf.constant_pool), + m.descriptor.getValue(cf.constant_pool)); + if (!CallerSensitiveFinder.isCallerSensitive(m, cf.constant_pool)) { + csMethodsMissingAnnotation.add(name); + System.err.println("Missing @CallerSensitive: " + name); + } else { + if (verbose) { + System.out.format("@CS %s%n", name); + } + } + } catch (ConstantPoolException ex) { + throw new RuntimeException(ex); + } + } + }; } public List run(List classes) throws IOException, InterruptedException, @@ -125,27 +162,12 @@ public class CallerSensitiveFinder extends MethodFinder { return false; } - public void referenceFound(ClassFile cf, Method m, Set refs) - throws ConstantPoolException - { - String name = String.format("%s#%s %s", cf.getName(), - m.getName(cf.constant_pool), - m.descriptor.getValue(cf.constant_pool)); - if (!CallerSensitiveFinder.isCallerSensitive(m, cf.constant_pool)) { - csMethodsMissingAnnotation.add(name); - System.err.println("Missing @CallerSensitive: " + name); - } else { - if (verbose) { - System.out.format("@CS %s%n", name); - } - } - } - - private final List> tasks = new ArrayList>(); - private FutureTask getTask(final ClassFile cf) { - FutureTask task = new FutureTask(new Callable() { - public String call() throws Exception { - return parse(cf); + private final List> tasks = new ArrayList>(); + private FutureTask getTask(final ClassFile cf) { + FutureTask task = new FutureTask(new Callable() { + public Void call() throws Exception { + finder.parse(cf); + return null; } }); tasks.add(task); @@ -153,8 +175,8 @@ public class CallerSensitiveFinder extends MethodFinder { } private void waitForCompletion() throws InterruptedException, ExecutionException { - for (FutureTask t : tasks) { - String s = t.get(); + for (FutureTask t : tasks) { + t.get(); } System.out.println("Parsed " + tasks.size() + " classfiles"); } diff --git a/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java b/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java deleted file mode 100644 index 8ea78866dae..00000000000 --- a/jdk/test/sun/reflect/CallerSensitive/MethodFinder.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.*; -import com.sun.tools.classfile.*; -import static com.sun.tools.classfile.ConstantPool.*; -import com.sun.tools.classfile.Instruction.TypeKind; - -/** - * MethodFinder utility class to find references to the given methods. - */ -public abstract class MethodFinder { - final List methods; - public MethodFinder(String... methods) { - this.methods = Arrays.asList(methods); - } - - /** - * A callback method will be invoked when a method referencing - * any of the lookup methods. - * - * @param cf ClassFile - * @param m Method - * @param refs Set of constant pool indices that reference the methods - * matching the given lookup method names - */ - public abstract void referenceFound(ClassFile cf, Method m, Set refs) - throws ConstantPoolException; - - public String parse(ClassFile cf) throws ConstantPoolException { - List cprefs = new ArrayList(); - int index = 1; - for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) { - if (cpInfo.accept(cpVisitor, null)) { - cprefs.add(index); - } - index += cpInfo.size(); - } - - if (!cprefs.isEmpty()) { - for (Method m : cf.methods) { - Set refs = new HashSet(); - Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code); - if (c_attr != null) { - for (Instruction instr : c_attr.getInstructions()) { - int idx = instr.accept(codeVisitor, cprefs); - if (idx > 0) { - refs.add(idx); - } - } - } - if (refs.size() > 0) { - referenceFound(cf, m, refs); - } - } - } - return cprefs.isEmpty() ? "" : cf.getName(); - } - - private ConstantPool.Visitor cpVisitor = - new ConstantPool.Visitor() - { - private boolean matches(CPRefInfo info) { - try { - CONSTANT_NameAndType_info nat = info.getNameAndTypeInfo(); - return matches(info.getClassName(), nat.getName(), nat.getType()); - } catch (ConstantPoolException ex) { - return false; - } - } - - private boolean matches(String cn, String name, String type) { - return methods.contains(cn + "." + name); - } - - public Boolean visitClass(CONSTANT_Class_info info, Void p) { - return false; - } - - public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { - return matches(info); - } - - public Boolean visitMethodref(CONSTANT_Methodref_info info, Void p) { - return matches(info); - } - - public Boolean visitDouble(CONSTANT_Double_info info, Void p) { - return false; - } - - public Boolean visitFieldref(CONSTANT_Fieldref_info info, Void p) { - return false; - } - - public Boolean visitFloat(CONSTANT_Float_info info, Void p) { - return false; - } - - public Boolean visitInteger(CONSTANT_Integer_info info, Void p) { - return false; - } - - public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) { - return false; - } - - public Boolean visitLong(CONSTANT_Long_info info, Void p) { - return false; - } - - public Boolean visitNameAndType(CONSTANT_NameAndType_info info, Void p) { - return false; - } - - public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) { - return false; - } - - public Boolean visitMethodType(CONSTANT_MethodType_info info, Void p) { - return false; - } - - public Boolean visitString(CONSTANT_String_info info, Void p) { - return false; - } - - public Boolean visitUtf8(CONSTANT_Utf8_info info, Void p) { - return false; - } - }; - - private Instruction.KindVisitor> codeVisitor = - new Instruction.KindVisitor>() - { - public Integer visitNoOperands(Instruction instr, List p) { - return 0; - } - - public Integer visitArrayType(Instruction instr, TypeKind kind, List p) { - return 0; - } - - public Integer visitBranch(Instruction instr, int offset, List p) { - return 0; - } - - public Integer visitConstantPoolRef(Instruction instr, int index, List p) { - return p.contains(index) ? index : 0; - } - - public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List p) { - return p.contains(index) ? index : 0; - } - - public Integer visitLocal(Instruction instr, int index, List p) { - return 0; - } - - public Integer visitLocalAndValue(Instruction instr, int index, int value, List p) { - return 0; - } - - public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List p) { - return 0; - } - - public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List p) { - return 0; - } - - public Integer visitValue(Instruction instr, int value, List p) { - return 0; - } - - public Integer visitUnknown(Instruction instr, List p) { - return 0; - } - }; -} - diff --git a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java index c60a8d0eca5..4fe6ba68a21 100644 --- a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java +++ b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java @@ -27,7 +27,7 @@ * @bug 8010117 * @summary Test CallerSensitiveFinder to find missing annotation * @compile -XDignore.symbol.file MissingCallerSensitive.java - * @build CallerSensitiveFinder MethodFinder + * @build CallerSensitiveFinder * @run main MissingCallerSensitive */ @@ -40,8 +40,7 @@ public class MissingCallerSensitive { List classes = new ArrayList<>(); classes.add(Paths.get(testclasses, "MissingCallerSensitive.class")); - final String method = "sun/reflect/Reflection.getCallerClass"; - CallerSensitiveFinder csfinder = new CallerSensitiveFinder(method); + CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); if (errors.size() != 1) { throw new RuntimeException("Unexpected number of methods found: " + errors.size()); diff --git a/jdk/test/sun/security/krb5/auto/SSL.java b/jdk/test/sun/security/krb5/auto/SSL.java index 353916e7578..8d64460430d 100644 --- a/jdk/test/sun/security/krb5/auto/SSL.java +++ b/jdk/test/sun/security/krb5/auto/SSL.java @@ -23,10 +23,11 @@ /* * @test - * @bug 6894643 6913636 + * @bug 6894643 6913636 8005523 * @summary Test JSSE Kerberos ciphersuite + * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA - * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_MD5 + * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_SHA * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_MD5 * @run main/othervm SSL TLS_KRB5_WITH_DES_CBC_SHA @@ -38,14 +39,17 @@ */ import java.io.*; import java.net.InetAddress; +import java.security.AccessControlException; +import java.security.Permission; import javax.net.ssl.*; import java.security.Principal; import java.util.Date; +import javax.security.auth.kerberos.ServicePermission; import sun.security.jgss.GSSUtil; import sun.security.krb5.PrincipalName; import sun.security.krb5.internal.ktab.KeyTab; -public class SSL { +public class SSL extends SecurityManager { private static String krb5Cipher; private static final int LOOP_LIMIT = 3; @@ -53,13 +57,32 @@ public class SSL { private static volatile String server; private static volatile int port; + private static String permChecks = ""; + // 0-Not started, 1-Start OK, 2-Failure private static volatile int serverState = 0; + @Override + public void checkPermission(Permission perm, Object context) { + checkPermission(perm); + } + + public void checkPermission(Permission perm) { + if (!(perm instanceof ServicePermission)) { + return; + } + ServicePermission p = (ServicePermission)perm; + permChecks = permChecks + p.getActions().toUpperCase().charAt(0); + } + public static void main(String[] args) throws Exception { krb5Cipher = args[0]; + boolean unbound = args.length > 1; + + System.setSecurityManager(new SSL()); + KDC kdc = KDC.create(OneKDC.REALM); // Run this after KDC, so our own DNS service can be started try { @@ -85,6 +108,7 @@ public class SSL { // and use the middle one as the real key kdc.addPrincipal("host/" + server, "pass2".toCharArray()); + // JAAS config entry name ssl System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF); File f = new File(OneKDC.JAAS_CONF); @@ -92,7 +116,9 @@ public class SSL { fos.write(( "ssl {\n" + " com.sun.security.auth.module.Krb5LoginModule required\n" + - " principal=\"host/" + server + "\"\n" + + (unbound ? + " principal=*\n" : + " principal=\"host/" + server + "\"\n") + " useKeyTab=true\n" + " keyTab=" + OneKDC.KTAB + "\n" + " isInitiator=false\n" + @@ -103,7 +129,6 @@ public class SSL { Context c; final Context s = Context.fromJAAS("ssl"); - // There's no keytab file when server starts. s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); Thread server = new Thread(new Runnable() { @@ -127,21 +152,6 @@ public class SSL { throw new Exception("Server already failed"); } - // Now create the keytab - - /* - // Add 3 versions of keys into keytab - KeyTab ktab = KeyTab.create(OneKDC.KTAB); - PrincipalName service = new PrincipalName( - "host/" + server, PrincipalName.KRB_NT_SRV_HST); - ktab.addEntry(service, "pass1".toCharArray(), 1); - ktab.addEntry(service, "pass2".toCharArray(), 2); - ktab.addEntry(service, "pass3".toCharArray(), 3); - ktab.save(); - - // and use the middle one as the real key - kdc.addPrincipal("host/" + server, "pass2".toCharArray()); - */ c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID); c.doAs(new JsseClientAction(), null); @@ -157,20 +167,22 @@ public class SSL { c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID); c.doAs(new JsseClientAction(), null); - // Revoke the old key - /*Thread.sleep(2000); - ktab = KeyTab.create(OneKDC.KTAB); - ktab.addEntry(service, "pass5".toCharArray(), 5, false); - ktab.save(); - - c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); - c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID); - try { - c.doAs(new JsseClientAction(), null); - throw new Exception("Should fail this time."); - } catch (SSLException e) { - // Correct behavior. - }*/ + // Permission checking check. Please note this is highly + // implementation related. + if (unbound) { + // For unbound, server does not know what name to check. + // Client checks "initiate", then server gets the name + // and checks "accept". Second connection resume. + if (!permChecks.equals("IA")) { + throw new Exception(); + } + } else { + // For bound, JAAS checks "accept" once. Server checks again, + // client then checks "initiate". Second connection resume. + if (!permChecks.equals("AAI")) { + throw new Exception(); + } + } } // Following codes copied from diff --git a/jdk/test/sun/security/krb5/auto/SaslGSS.java b/jdk/test/sun/security/krb5/auto/SaslGSS.java new file mode 100644 index 00000000000..e497ab1a296 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/SaslGSS.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8012082 + * @summary SASL: auth-conf negotiated, but unencrypted data is accepted, + * reset to unencrypt + * @compile -XDignore.symbol.file SaslGSS.java + * @run main/othervm SaslGSS + */ + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; +import javax.security.sasl.RealmCallback; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslServer; +import java.io.IOException; +import java.util.HashMap; +import java.util.Locale; +import org.ietf.jgss.*; +import sun.security.jgss.GSSUtil; + +public class SaslGSS { + + public static void main(String[] args) throws Exception { + + String name = "host." + OneKDC.REALM.toLowerCase(Locale.US); + + new OneKDC(null).writeJAASConf(); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + // Client in JGSS so that it can control wrap privacy mode + GSSManager m = GSSManager.getInstance(); + GSSContext sc = m.createContext( + m.createName(OneKDC.SERVER, GSSUtil.NT_GSS_KRB5_PRINCIPAL), + GSSUtil.GSS_KRB5_MECH_OID, + null, + GSSContext.DEFAULT_LIFETIME); + sc.requestMutualAuth(false); + + // Server in SASL + final HashMap props = new HashMap(); + props.put(Sasl.QOP, "auth-conf"); + SaslServer ss = Sasl.createSaslServer("GSSAPI", "server", + name, props, + new CallbackHandler() { + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException { + for (Callback cb : callbacks) { + if (cb instanceof RealmCallback) { + ((RealmCallback) cb).setText(OneKDC.REALM); + } else if (cb instanceof AuthorizeCallback) { + ((AuthorizeCallback) cb).setAuthorized(true); + } + } + } + }); + + // Handshake + byte[] token = new byte[0]; + token = sc.initSecContext(token, 0, token.length); + token = ss.evaluateResponse(token); + token = sc.unwrap(token, 0, token.length, new MessageProp(0, false)); + token[0] = (byte)(((token[0] & 4) != 0) ? 4 : 2); + token = sc.wrap(token, 0, token.length, new MessageProp(0, false)); + ss.evaluateResponse(token); + + // Talk + // 1. Client sends a auth-int message + byte[] hello = "hello".getBytes(); + MessageProp qop = new MessageProp(0, false); + token = sc.wrap(hello, 0, hello.length, qop); + // 2. Server accepts it anyway + ss.unwrap(token, 0, token.length); + // 3. Server sends a message + token = ss.wrap(hello, 0, hello.length); + // 4. Client accepts, should be auth-conf + sc.unwrap(token, 0, token.length, qop); + if (!qop.getPrivacy()) { + throw new Exception(); + } + } +} diff --git a/jdk/test/sun/security/provider/SecureRandom/StrongSeedReader.java b/jdk/test/sun/security/provider/SecureRandom/StrongSeedReader.java index 34f10f1d6a3..7057f9b2bb4 100644 --- a/jdk/test/sun/security/provider/SecureRandom/StrongSeedReader.java +++ b/jdk/test/sun/security/provider/SecureRandom/StrongSeedReader.java @@ -49,7 +49,7 @@ public class StrongSeedReader { File file = null; try { - file = new File(System.getProperty("java.io.tmpdir") + + file = new File(System.getProperty("java.io.tmpdir"), "StrongSeedReader.tmpdata"); // write a bunch of 0's to the file. diff --git a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java index 208f51943de..237d61f033e 100644 --- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java +++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java @@ -260,6 +260,8 @@ public class TimestampCheck { jarsigner(cmd, 7, false); // tsbad2 jarsigner(cmd, 8, false); // tsbad3 jarsigner(cmd, 9, false); // no cert in timestamp + jarsigner(cmd + " -tsapolicyid 1.2.3.4", 0, true); + jarsigner(cmd + " -tsapolicyid 1.2.3.5", 0, false); } else { // Run as a standalone server System.err.println("Press Enter to quit server"); System.in.read(); diff --git a/jdk/test/sun/security/tools/jarsigner/ts.sh b/jdk/test/sun/security/tools/jarsigner/ts.sh index 43a3651f62a..e318ca677e0 100644 --- a/jdk/test/sun/security/tools/jarsigner/ts.sh +++ b/jdk/test/sun/security/tools/jarsigner/ts.sh @@ -22,7 +22,7 @@ # # @test -# @bug 6543842 6543440 6939248 +# @bug 6543842 6543440 6939248 8009636 # @summary checking response of timestamp # # @run shell/timeout=600 ts.sh diff --git a/jdk/test/sun/security/tools/keytool/console.sh b/jdk/test/sun/security/tools/keytool/console.sh index ec0f05961f8..ec338ca373d 100644 --- a/jdk/test/sun/security/tools/keytool/console.sh +++ b/jdk/test/sun/security/tools/keytool/console.sh @@ -1,5 +1,3 @@ -#! /bin/sh - # # Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,10 +22,11 @@ # # @test -# @bug 6418647 +# @bug 6418647 8005527 # @summary Doc bug 5035358 shows sun.security.util.Password.readPassword() is buggy. # @author Weijun Wang -# +# @ignore unable to test manual tools that have input from stdin, +# and output to stderr and stdout # @run shell/manual console.sh if [ "$ALT_PASS" = "" ]; then