From 94c6fd7bc607b6d3e59dc23e354aa86e3a8ccf27 Mon Sep 17 00:00:00 2001 From: Tatiana Pivovarova Date: Wed, 24 Dec 2014 17:54:00 +0300 Subject: [PATCH 01/72] 8067173: remove Utils::fileAsList Reviewed-by: kvn, iignatyev --- .../testlibrary/jdk/testlibrary/Utils.java | 19 ------------------- jdk/test/sun/tools/jcmd/TestJcmdDefaults.java | 9 ++++++--- jdk/test/sun/tools/jcmd/TestJcmdSanity.java | 9 ++++++--- jdk/test/sun/tools/jps/JpsHelper.java | 9 ++++++--- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java index af8cc267493..6c8f4f2794c 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java @@ -270,25 +270,6 @@ public final class Utils { } } - /** - * Returns file content as a list of strings - * - * @param file File to operate on - * @return List of strings - * @throws IOException - */ - public static List fileAsList(File file) throws IOException { - assertTrue(file.exists() && file.isFile(), - file.getAbsolutePath() + " does not exist or not a file"); - List output = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) { - while (reader.ready()) { - output.add(reader.readLine().replace(NEW_LINE, "")); - } - } - return output; - } - /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted diff --git a/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java b/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java index 2292be403da..c13b4d5da11 100644 --- a/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java +++ b/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java @@ -25,6 +25,9 @@ import static jdk.testlibrary.Asserts.*; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -95,11 +98,11 @@ public class TestJcmdDefaults { } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff --git a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java index 89152216010..8479730f52c 100644 --- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java +++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java @@ -25,6 +25,9 @@ import static jdk.testlibrary.Asserts.*; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -160,11 +163,11 @@ public class TestJcmdSanity { } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "help_help.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "help_help.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff --git a/jdk/test/sun/tools/jps/JpsHelper.java b/jdk/test/sun/tools/jps/JpsHelper.java index 079ae03d67e..e28e92dae73 100644 --- a/jdk/test/sun/tools/jps/JpsHelper.java +++ b/jdk/test/sun/tools/jps/JpsHelper.java @@ -28,6 +28,9 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -189,11 +192,11 @@ public final class JpsHelper { */ public static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { String testSrc = System.getProperty("test.src", "?"); - File file = new File(testSrc, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(testSrc, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } private static File getManifest(String className) throws IOException { From 4a438d1f982693245f5de0eb94d3dc94212897b1 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Fri, 12 Dec 2014 00:40:56 +0300 Subject: [PATCH 02/72] 8067291: Need additional vm checks in jdk/test/lib/testlibrary/jdk/testlibrary/Platform, checking which vm is run Reviewed-by: fzhinkin, iignatyev --- jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java index 6b92c28f057..6382e01c962 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java @@ -28,6 +28,15 @@ public class Platform { private static final String dataModel = System.getProperty("sun.arch.data.model"); private static final String vmVersion = System.getProperty("java.vm.version"); private static final String osArch = System.getProperty("os.arch"); + private static final String vmName = System.getProperty("java.vm.name"); + + public static boolean isClient() { + return vmName.endsWith(" Client VM"); + } + + public static boolean isServer() { + return vmName.endsWith(" Server VM"); + } public static boolean is32bit() { return dataModel.equals("32"); From a8c7ba21291c83221dd067ead70e13099e196a73 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Fri, 12 Dec 2014 21:16:42 +0300 Subject: [PATCH 03/72] 8067307: Need custom classloaders(parent-last and filtering one) for JDK-8066625 in testlibrary Reviewed-by: fzhinkin, iignatyev --- .../jdk/testlibrary/FilterClassLoader.java | 49 ++++++++++++++++++ .../testlibrary/ParentLastURLClassLoader.java | 50 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java create mode 100644 jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java b/jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java new file mode 100644 index 00000000000..fc4e82857f4 --- /dev/null +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.testlibrary; + +import java.util.function.Predicate; +/** + * A classloader, which using target classloader in case provided condition + * for class name is met, and using parent otherwise + */ +public class FilterClassLoader extends ClassLoader { + + private final ClassLoader target; + private final Predicate condition; + + public FilterClassLoader(ClassLoader target, ClassLoader parent, + Predicate condition) { + super(parent); + this.condition = condition; + this.target = target; + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (condition.test(name)) { + return target.loadClass(name); + } + return super.loadClass(name); + } +} diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java new file mode 100644 index 00000000000..203db612bf3 --- /dev/null +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.testlibrary; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * An url classloader, which trying to load class from provided URL[] first, + * and using parent classloader in case it failed + */ +public class ParentLastURLClassLoader extends URLClassLoader { + + public ParentLastURLClassLoader(URL urls[], ClassLoader parent) { + super(urls, parent); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + Class c = findClass(name); + if (c != null) { + return c; + } + } catch (ClassNotFoundException e) { + // ignore + } + return super.loadClass(name); + } +} From f2e6ba9b09f46ef7aa5eff0ed6f947e53d0aee0a Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Sat, 13 Dec 2014 00:10:55 +0300 Subject: [PATCH 04/72] 8059613: JEP-JDK-8043304: Test task: JMX- tests Reviewed-by: thartmann, twisti --- test/lib/sun/hotspot/code/BlobType.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/lib/sun/hotspot/code/BlobType.java b/test/lib/sun/hotspot/code/BlobType.java index 49d3a0a03d2..905f0ca00d1 100644 --- a/test/lib/sun/hotspot/code/BlobType.java +++ b/test/lib/sun/hotspot/code/BlobType.java @@ -32,11 +32,11 @@ import sun.hotspot.WhiteBox; public enum BlobType { // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) - MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), + MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'", "NonProfiledCodeHeapSize"), // Execution level 2 and 3 (profiled) nmethods - MethodProfiled(1, "CodeHeap 'profiled nmethods'"), + MethodProfiled(1, "CodeHeap 'profiled nmethods'", "ProfiledCodeHeapSize"), // Non-nmethods like Buffers, Adapters and Runtime Stubs - NonNMethod(2, "CodeHeap 'non-nmethods'") { + NonNMethod(2, "CodeHeap 'non-nmethods'", "NonNMethodCodeHeapSize") { @Override public boolean allowTypeWhenOverflow(BlobType type) { return super.allowTypeWhenOverflow(type) @@ -44,14 +44,16 @@ public enum BlobType { } }, // All types (No code cache segmentation) - All(3, "CodeCache"); + All(3, "CodeCache", "ReservedCodeCacheSize"); public final int id; - private final String beanName; + public final String sizeOptionName; + public final String beanName; - private BlobType(int id, String beanName) { + private BlobType(int id, String beanName, String sizeOptionName) { this.id = id; this.beanName = beanName; + this.sizeOptionName = sizeOptionName; } public MemoryPoolMXBean getMemoryPool() { @@ -87,4 +89,8 @@ public enum BlobType { } return result; } + + public long getSize() { + return WhiteBox.getWhiteBox().getUintxVMFlag(sizeOptionName); + } } From 3b00992919869f33a809ed318a921ffd8808dbe1 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Sat, 13 Dec 2014 00:54:22 +0300 Subject: [PATCH 05/72] 8066440: Various changes in testlibrary for JDK-8059613 Reviewed-by: thartmann, twisti --- .../com/oracle/java/testlibrary/Utils.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java index ddd16f8ab2f..ef571a0960b 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java @@ -40,6 +40,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; +import java.util.function.BooleanSupplier; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -395,6 +396,52 @@ public final class Utils { return RANDOM_GENERATOR; } + /** + * Wait for condition to be true + * + * @param condition, a condition to wait for + */ + public static final void waitForCondition(BooleanSupplier condition) { + waitForCondition(condition, -1L, 100L); + } + + /** + * Wait until timeout for condition to be true + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true + * specifying -1 will wait forever + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout) { + return waitForCondition(condition, timeout, 100L); + } + + /** + * Wait until timeout for condition to be true for specified time + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true, + * specifying -1 will wait forever + * @param sleepTime a time to sleep value in milliseconds + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout, long sleepTime) { + long startTime = System.currentTimeMillis(); + while (!(condition.getAsBoolean() || (timeout != -1L + && ((System.currentTimeMillis() - startTime) > timeout)))) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + return condition.getAsBoolean(); + } + /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted From e42d9168db5038ec6c3bd929d81c847ebfc42c03 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Sat, 13 Dec 2014 00:13:05 +0300 Subject: [PATCH 06/72] 8059613: JEP-JDK-8043304: Test task: JMX- tests Reviewed-by: thartmann, twisti --- hotspot/test/TEST.groups | 1 + .../compiler/codecache/jmx/BeanTypeTest.java | 47 +++++++ .../codecache/jmx/CodeCacheUtils.java | 101 ++++++++++++++ .../jmx/CodeHeapBeanPresenceTest.java | 55 ++++++++ .../compiler/codecache/jmx/GetUsageTest.java | 109 +++++++++++++++ .../codecache/jmx/InitialAndMaxUsageTest.java | 107 ++++++++++++++ .../codecache/jmx/ManagerNamesTest.java | 64 +++++++++ .../jmx/MemoryPoolsPresenceTest.java | 77 ++++++++++ .../compiler/codecache/jmx/PeakUsageTest.java | 97 +++++++++++++ .../codecache/jmx/PoolsIndependenceTest.java | 131 ++++++++++++++++++ .../jmx/ThresholdNotificationsTest.java | 102 ++++++++++++++ ...sageThresholdExceededSeveralTimesTest.java | 36 +++++ .../jmx/UsageThresholdExceededTest.java | 73 ++++++++++ .../jmx/UsageThresholdIncreasedTest.java | 88 ++++++++++++ .../jmx/UsageThresholdNotExceededTest.java | 75 ++++++++++ 15 files changed, 1163 insertions(+) create mode 100644 hotspot/test/compiler/codecache/jmx/BeanTypeTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java create mode 100644 hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/GetUsageTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/PeakUsageTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java create mode 100644 hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 261e0cf073c..5baf020e4be 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -145,6 +145,7 @@ needs_compact3 = \ gc/survivorAlignment \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ serviceability/threads/TestFalseDeadLock.java \ + compiler/codecache/jmx # Compact 2 adds full VM tests compact2 = \ diff --git a/hotspot/test/compiler/codecache/jmx/BeanTypeTest.java b/hotspot/test/compiler/codecache/jmx/BeanTypeTest.java new file mode 100644 index 00000000000..9ce162d2c28 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/BeanTypeTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryType; +import sun.hotspot.code.BlobType; + +/** + * @test BeanTypeTest + * @library /testlibrary /../../test/lib + * @build BeanTypeTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache BeanTypeTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache BeanTypeTest + * @summary verify types of code cache memory pool bean + */ +public class BeanTypeTest { + + public static void main(String args[]) { + for (BlobType bt : BlobType.getAvailable()) { + Asserts.assertEQ(MemoryType.NON_HEAP, bt.getMemoryPool().getType()); + } + } +} diff --git a/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java b/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java new file mode 100644 index 00000000000..472a88117b8 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Utils; +import java.lang.management.MemoryPoolMXBean; +import javax.management.Notification; +import sun.hotspot.WhiteBox; +import sun.hotspot.code.BlobType; +import sun.hotspot.code.CodeBlob; + +public final class CodeCacheUtils { + + /** + * Returns the value to be used for code heap allocation + */ + public static final int ALLOCATION_SIZE + = Integer.getInteger("codecache.allocation.size", 100); + public static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static final long SEGMENT_SIZE + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheSegmentSize"); + public static final long MIN_BLOCK_LENGTH + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheMinBlockLength"); + public static final long MIN_ALLOCATION = SEGMENT_SIZE * MIN_BLOCK_LENGTH; + + private CodeCacheUtils() { + // To prevent from instantiation + } + + public static final void hitUsageThreshold(MemoryPoolMXBean bean, + BlobType btype) { + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + 1); + long usageThresholdCount = bean.getUsageThresholdCount(); + long addr = WB.allocateCodeBlob(1, btype.id); + WB.fullGC(); + Utils.waitForCondition(() + -> bean.getUsageThresholdCount() == usageThresholdCount + 1); + WB.freeCodeBlob(addr); + } + + public static final long getHeaderSize(BlobType btype) { + long addr = WB.allocateCodeBlob(0, btype.id); + int size = CodeBlob.getCodeBlob(addr).size; + WB.freeCodeBlob(addr); + return size; + } + + public static String getPoolNameFromNotification( + Notification notification) { + return ((javax.management.openmbean.CompositeDataSupport) + notification.getUserData()).get("poolName").toString(); + } + + public static boolean isAvailableCodeHeapPoolName(String name) { + return BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .map(MemoryPoolMXBean::getName) + .filter(name::equals) + .findAny().isPresent(); + } + + /** + * A "non-nmethods" code heap is used by interpreter during bytecode + * execution, thus, it can't be predicted if this code heap usage will be + * increased or not. Same goes for 'All'. + * + * @param btype BlobType to be checked + * @return boolean value, true if respective code heap is predictable + */ + public static boolean isCodeHeapPredictable(BlobType btype) { + return btype == BlobType.MethodNonProfiled + || btype == BlobType.MethodProfiled; + } + + public static void disableCollectionUsageThresholds(){ + BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .filter(MemoryPoolMXBean::isCollectionUsageThresholdSupported) + .forEach(b -> b.setCollectionUsageThreshold(0L)); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java b/hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java new file mode 100644 index 00000000000..1ebacf95971 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.util.EnumSet; +import sun.hotspot.code.BlobType; + +/** + * @test CodeHeapBeanPresenceTest + * @library /testlibrary /../../test/lib + * @build CodeHeapBeanPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache CodeHeapBeanPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache CodeHeapBeanPresenceTest + * @summary verify CodeHeap bean presence + */ +public class CodeHeapBeanPresenceTest { + + public static void main(String args[]) { + EnumSet shouldBeAvailable = BlobType.getAvailable(); + EnumSet shouldNotBeAvailable + = EnumSet.complementOf(shouldBeAvailable); + for (BlobType btype : shouldBeAvailable) { + Asserts.assertNotNull(btype.getMemoryPool(), + "Can't find memory pool for " + btype.name()); + } + for (BlobType btype : shouldNotBeAvailable) { + Asserts.assertNull(btype.getMemoryPool(), + "Memory pool unexpected for " + btype.name()); + } + } +} diff --git a/hotspot/test/compiler/codecache/jmx/GetUsageTest.java b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java new file mode 100644 index 00000000000..87139abd65f --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import sun.hotspot.code.BlobType; + +/* + * @test GetUsageTest + * @library /testlibrary /../../test/lib + * @build GetUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:CompileCommand=compileonly,null::* + * -XX:-UseCodeCacheFlushing -XX:-MethodFlushing -XX:+SegmentedCodeCache + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI GetUsageTest + * @summary testing of getUsage() for segmented code cache + */ +public class GetUsageTest { + + private final BlobType btype; + private final int allocateSize; + + public GetUsageTest(BlobType btype, int allocSize) { + this.btype = btype; + this.allocateSize = allocSize; + } + + public static void main(String[] args) throws Exception { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + for (int allocSize = 10; allocSize < 100000; allocSize *= 10) { + new GetUsageTest(btype, allocSize).runTest(); + } + } + } + } + + protected final Map getBeanUsages() { + Map beanUsages = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + beanUsages.put(bt.getMemoryPool(), + bt.getMemoryPool().getUsage().getUsed()); + } + return beanUsages; + } + + protected void runTest() { + MemoryPoolMXBean[] predictableBeans = BlobType.getAvailable().stream() + .filter(CodeCacheUtils::isCodeHeapPredictable) + .map(BlobType::getMemoryPool) + .toArray(MemoryPoolMXBean[]::new); + Map initial = getBeanUsages(); + long addr = 0; + try { + addr = CodeCacheUtils.WB.allocateCodeBlob(allocateSize, btype.id); + Map current = getBeanUsages(); + long blockCount = Math.floorDiv(allocateSize + + CodeCacheUtils.getHeaderSize(btype) + + CodeCacheUtils.SEGMENT_SIZE - 1, CodeCacheUtils.SEGMENT_SIZE); + long usageUpperEstimate = Math.max(blockCount, + CodeCacheUtils.MIN_BLOCK_LENGTH) * CodeCacheUtils.SEGMENT_SIZE; + for (MemoryPoolMXBean entry : predictableBeans) { + long diff = current.get(entry) - initial.get(entry); + if (entry.equals(btype.getMemoryPool())) { + Asserts.assertFalse(diff <= 0L || diff > usageUpperEstimate, + String.format("Pool %s usage increase was reported " + + "unexpectedly as increased by %d using " + + "allocation size %d", entry.getName(), + diff, allocateSize)); + } else { + Asserts.assertEQ(diff, 0L, + String.format("Pool %s usage changed unexpectedly while" + + " trying to increase: %s using allocation " + + "size %d", entry.getName(), + btype.getMemoryPool().getName(), allocateSize)); + } + } + } finally { + if (addr != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + btype.getMemoryPool().getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java new file mode 100644 index 00000000000..e18be5cab98 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.ArrayList; +import java.util.List; +import sun.hotspot.code.BlobType; + +/* + * @test InitialAndMaxUsageTest + * @library /testlibrary /../../test/lib + * @build InitialAndMaxUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * InitialAndMaxUsageTest + * @summary testing of initial and max usage + */ +public class InitialAndMaxUsageTest { + + private static final double CACHE_USAGE_COEF = 0.95d; + private final BlobType btype; + private final boolean lowerBoundIsZero; + private final long maxSize; + + public InitialAndMaxUsageTest(BlobType btype) { + this.btype = btype; + this.maxSize = btype.getSize(); + /* Only profiled code cache initial size should be 0, because of + -XX:CompileCommand=compileonly,null::* non-methods might be not empty, + as well as non-profiled methods, because it's used as fallback in + case non-methods is full */ + lowerBoundIsZero = btype == BlobType.MethodProfiled; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new InitialAndMaxUsageTest(btype).runTest(); + } + } + + private void fillWithSize(long size, List blobs) { + long blob; + while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) + != 0L) { + blobs.add(blob); + } + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialUsage = btype.getMemoryPool().getUsage().getUsed(); + System.out.printf("INFO: trying to test %s of max size %d and initial" + + " usage %d%n", bean.getName(), maxSize, initialUsage); + Asserts.assertLT(initialUsage + headerSize + 1L, maxSize, + "Initial usage is close to total size for " + bean.getName()); + if (lowerBoundIsZero) { + Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage"); + } + ArrayList blobs = new ArrayList<>(); + long minAllocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + /* now filling code cache with large-sized allocation first, since + lots of small allocations takes too much time, so, just a small + optimization */ + try { + for (int coef = 1000000; coef > 0; coef /= 10) { + fillWithSize(coef * minAllocationUnit, blobs); + } + Asserts.assertGT((double) bean.getUsage().getUsed(), + CACHE_USAGE_COEF * maxSize, String.format("Unable to fill " + + "more than %f of %s. Reported usage is %d ", + CACHE_USAGE_COEF, bean.getName(), + bean.getUsage().getUsed())); + } finally { + for (long entry : blobs) { + CodeCacheUtils.WB.freeCodeBlob(entry); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } + +} diff --git a/hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java b/hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java new file mode 100644 index 00000000000..57be84e2b48 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/** + * @test ManagerNamesTest + * @library /testlibrary /../../test/lib + * @build ManagerNamesTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache ManagerNamesTest + * * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache ManagerNamesTest + * @summary verify getMemoryManageNames calls in case of segmented code cache + */ +public class ManagerNamesTest { + + private final MemoryPoolMXBean bean; + private final static String POOL_NAME = "CodeCacheManager"; + + public static void main(String args[]) { + for (BlobType btype : BlobType.getAvailable()) { + new ManagerNamesTest(btype).runTest(); + } + } + + public ManagerNamesTest(BlobType btype) { + bean = btype.getMemoryPool(); + } + + protected void runTest() { + String[] names = bean.getMemoryManagerNames(); + Asserts.assertEQ(names.length, 1, + "Unexpected length of MemoryManagerNames"); + Asserts.assertEQ(POOL_NAME, names[0], + "Unexpected value of MemoryManagerName"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java b/hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java new file mode 100644 index 00000000000..d850e926eb1 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryManagerMXBean; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import sun.hotspot.code.BlobType; + +/** + * @test MemoryPoolsPresenceTest + * @library /testlibrary /../../test/lib + * @build MemoryPoolsPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache MemoryPoolsPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache MemoryPoolsPresenceTest + * @summary verify that MemoryManagerMXBean exists for every code cache segment + */ +public class MemoryPoolsPresenceTest { + + private static final String CC_MANAGER = "CodeCacheManager"; + private final Map counters = new HashMap<>(); + + public static void main(String args[]) { + new MemoryPoolsPresenceTest().runTest(); + } + + protected void runTest() { + List beans + = ManagementFactory.getMemoryManagerMXBeans(); + Optional any = beans + .stream() + .filter(bean -> CC_MANAGER.equals(bean.getName())) + .findAny(); + Asserts.assertTrue(any.isPresent(), "Bean not found: " + CC_MANAGER); + MemoryManagerMXBean ccManager = any.get(); + Asserts.assertNotNull(ccManager, "Found null for " + CC_MANAGER); + String names[] = ccManager.getMemoryPoolNames(); + for (String name : names) { + counters.put(name, counters.containsKey(name) + ? counters.get(name) + 1 : 1); + } + for (BlobType btype : BlobType.getAvailable()) { + Asserts.assertEQ(counters.get(btype.getMemoryPool().getName()), 1, + "Found unexpected amount of beans for pool " + + btype.getMemoryPool().getName()); + } + Asserts.assertEQ(BlobType.getAvailable().size(), + counters.keySet().size(), "Unexpected amount of bean names"); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java new file mode 100644 index 00000000000..b77e054c374 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test PeakUsageTest + * @library /testlibrary /../../test/lib + * @build PeakUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* PeakUsageTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* PeakUsageTest + * @summary testing of getPeakUsage() and resetPeakUsage for + * segmented code cache + */ +public class PeakUsageTest { + + private final BlobType btype; + + public PeakUsageTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new PeakUsageTest(btype).runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + bean.resetPeakUsage(); + long addr = CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + long newPeakUsage = bean.getPeakUsage().getUsed(); + try { + Asserts.assertEQ(newPeakUsage, bean.getUsage().getUsed(), + "Peak usage does not match usage after allocation for " + + bean.getName()); + } finally { + if (addr != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr); + } + } + Asserts.assertEQ(newPeakUsage, bean.getPeakUsage().getUsed(), + "Code cache peak usage has changed after usage decreased for " + + bean.getName()); + bean.resetPeakUsage(); + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after reset for " + + bean.getName()); + long addr2 = CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + try { + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after fresh " + + "allocation for " + bean.getName()); + } finally { + if (addr2 != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr2); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java new file mode 100644 index 00000000000..a2ea70a1fe2 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test PoolsIndependenceTest + * @library /testlibrary /../../test/lib + * @build PoolsIndependenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache PoolsIndependenceTest + * @summary testing of getUsageThreshold() + */ +public class PoolsIndependenceTest implements NotificationListener { + + private final Map counters; + private final BlobType btype; + private volatile long lastEventTimestamp; + + public PoolsIndependenceTest(BlobType btype) { + counters = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + counters.put(bt.getMemoryPool().getName(), new AtomicInteger(0)); + } + this.btype = btype; + lastEventTimestamp = 0; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new PoolsIndependenceTest(bt).runTest(); + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + bean.setUsageThreshold(bean.getUsage().getUsed() + 1); + long beginTimestamp = System.currentTimeMillis(); + CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + CodeCacheUtils.WB.fullGC(); + /* waiting for expected event to be received plus double the time took + to receive expected event(for possible unexpected) and + plus 1 second in case expected event received (almost)immediately */ + Utils.waitForCondition(() -> { + long currentTimestamp = System.currentTimeMillis(); + int eventsCount + = counters.get(btype.getMemoryPool().getName()).get(); + if (eventsCount > 0) { + if (eventsCount > 1) { + return true; + } + long timeLastEventTook + = beginTimestamp - lastEventTimestamp; + long timeoutValue + = 1000L + beginTimestamp + 3L * timeLastEventTook; + return currentTimestamp > timeoutValue; + } + return false; + }); + for (BlobType bt : BlobType.getAvailable()) { + int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0; + Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(), + expectedNotificationsAmount, String.format("Unexpected " + + "amount of notifications for pool: %s", + bt.getMemoryPool().getName())); + } + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario with %s finished%n", bean.getName()); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + // receiving events from available CodeCache-related beans only + if (counters.get(poolName) != null) { + counters.get(poolName).incrementAndGet(); + lastEventTimestamp = System.currentTimeMillis(); + } + } + } +} diff --git a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java new file mode 100644 index 00000000000..b03fbc2f4a7 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test ThresholdNotificationsTest + * @library /testlibrary /../../test/lib + * @build ThresholdNotificationsTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * ThresholdNotificationsTest + * @summary testing of getUsageThreshold() + */ +public class ThresholdNotificationsTest implements NotificationListener { + + private final static long WAIT_TIME = 10000L; + private volatile long counter; + private final BlobType btype; + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new ThresholdNotificationsTest(bt).runTest(); + } + } + + public ThresholdNotificationsTest(BlobType btype) { + this.btype = btype; + counter = 0L; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + if (poolName.equals(btype.getMemoryPool().getName())) { + counter++; + } + } + } + + protected void runTest() { + int iterationsCount = + Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + for (int i = 0; i < iterationsCount; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Asserts.assertTrue( + Utils.waitForCondition( + () -> counter == iterationsCount, WAIT_TIME), + "Couldn't receive expected notifications count"); + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java new file mode 100644 index 00000000000..ad2ddc8603c --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test UsageThresholdExceededSeveralTimesTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * -Dcom.oracle.java.testlibrary.iterations=10 UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit several times + */ diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java new file mode 100644 index 00000000000..50e455627d5 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdExceededTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* + * UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit + */ +public class UsageThresholdExceededTest { + + protected final int iterations; + private final BlobType btype; + + public UsageThresholdExceededTest(BlobType btype, int iterations) { + this.btype = btype; + this.iterations = iterations; + } + + public static void main(String[] args) { + int iterationsCount = + Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdExceededTest(btype, iterationsCount) + .runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long oldValue = bean.getUsageThresholdCount(); + for (int i = 0; i < iterations; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Asserts.assertEQ(bean.getUsageThresholdCount(), oldValue + iterations, + "Unexpected threshold usage count"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java new file mode 100644 index 00000000000..e70f62aa4dd --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdIncreasedTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdIncreasedTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* + * UsageThresholdIncreasedTest + * @summary verifying that threshold hasn't been hit after allocation smaller + * than threshold value and that threshold value can be changed + */ +public class UsageThresholdIncreasedTest { + + private static final int ALLOCATION_STEP = 5; + private static final long THRESHOLD_STEP = ALLOCATION_STEP + * CodeCacheUtils.MIN_ALLOCATION; + private final BlobType btype; + + public UsageThresholdIncreasedTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new UsageThresholdIncreasedTest(btype).runTest(); + } + } + + private void checkUsageThresholdCount(MemoryPoolMXBean bean, long count){ + Asserts.assertEQ(bean.getUsageThresholdCount(), count, + String.format("Usage threshold was hit: %d times for %s " + + "Threshold value: %d with current usage: %d", + bean.getUsageThresholdCount(), bean.getName(), + bean.getUsageThreshold(), bean.getUsage().getUsed())); + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + long allocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialCount = bean.getUsageThresholdCount(); + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + // Usage threshold check is triggered by GC cycle, so, call it + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + long filledSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(filledSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + System.out.println("INFO: Case finished successfully for " + bean.getName()); + } +} diff --git a/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java new file mode 100644 index 00000000000..23fdf9c7b82 --- /dev/null +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdNotExceededTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdNotExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * UsageThresholdNotExceededTest + * @summary verifying that usage threshold not exceeded while allocating less + * than usage threshold + */ +public class UsageThresholdNotExceededTest { + + private final BlobType btype; + + public UsageThresholdNotExceededTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdNotExceededTest(btype).runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialThresholdCount = bean.getUsageThresholdCount(); + long initialUsage = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialUsage + 1 + CodeCacheUtils.MIN_ALLOCATION); + CodeCacheUtils.WB.allocateCodeBlob(CodeCacheUtils.MIN_ALLOCATION + - CodeCacheUtils.getHeaderSize(btype), btype.id); + // a gc cycle triggers usage threshold recalculation + CodeCacheUtils.WB.fullGC(); + Asserts.assertEQ(bean.getUsageThresholdCount(), initialThresholdCount, + String.format("Usage threshold was hit: %d times for %s. " + + "Threshold value: %d with current usage: %d", + bean.getUsageThresholdCount(), bean.getName(), + bean.getUsageThreshold(), bean.getUsage().getUsed())); + + System.out.println("INFO: Case finished successfully for " + + bean.getName()); + } +} From 5325eb9993065951fb813f2daaf3a31eb6d677a4 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Sat, 13 Dec 2014 22:14:34 +0300 Subject: [PATCH 07/72] 8067295: Need to port Utils chagnes from JDK-8066440 into jdk workspace Reviewed-by: fzhinkin, iignatyev --- .../testlibrary/jdk/testlibrary/Utils.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java index 6c8f4f2794c..85081f42719 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java @@ -39,6 +39,7 @@ import java.util.Collections; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; /** * Common library for various test helper functions. @@ -279,4 +280,50 @@ public final class Utils { public static long adjustTimeout(long tOut) { return Math.round(tOut * Utils.TIMEOUT_FACTOR); } + + /** + * Wait for condition to be true + * + * @param condition, a condition to wait for + */ + public static final void waitForCondition(BooleanSupplier condition) { + waitForCondition(condition, -1L, 100L); + } + + /** + * Wait until timeout for condition to be true + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true + * specifying -1 will wait forever + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout) { + return waitForCondition(condition, timeout, 100L); + } + + /** + * Wait until timeout for condition to be true for specified time + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true, + * specifying -1 will wait forever + * @param sleepTime a time to sleep value in milliseconds + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout, long sleepTime) { + long startTime = System.currentTimeMillis(); + while (!(condition.getAsBoolean() || (timeout != -1L + && ((System.currentTimeMillis() - startTime) > timeout)))) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + return condition.getAsBoolean(); + } } From df2b7b193473ec55f6c711e35b70474e71f6afdc Mon Sep 17 00:00:00 2001 From: Tatiana Pivovarova Date: Fri, 19 Dec 2014 14:12:22 +0300 Subject: [PATCH 08/72] 8062012: test/compiler/ciReplay/TestSA.sh should be updated to work w/ modular image build Reviewed-by: kvn, fzhinkin, iignatyev --- hotspot/test/compiler/ciReplay/TestSA.sh | 3 +-- hotspot/test/compiler/ciReplay/common.sh | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/hotspot/test/compiler/ciReplay/TestSA.sh b/hotspot/test/compiler/ciReplay/TestSA.sh index cc5f5037e7a..bf98f1a7691 100644 --- a/hotspot/test/compiler/ciReplay/TestSA.sh +++ b/hotspot/test/compiler/ciReplay/TestSA.sh @@ -26,7 +26,7 @@ ## ## @test ## @bug 8011675 -## @ignore 8031978 +## @ignore 8029528 ## @summary testing of ciReplay with using generated by SA replay.txt ## @author igor.ignatyev@oracle.com ## @run shell TestSA.sh @@ -69,7 +69,6 @@ fi echo "dumpreplaydata -a > ${replay_data}" | \ ${JAVA} ${TESTOPTS} \ - -cp ${TESTJAVA}${FS}lib${FS}sa-jdi.jar \ sun.jvm.hotspot.CLHSDB ${JAVA} ${core_file} if [ ! -s ${replay_data} ] diff --git a/hotspot/test/compiler/ciReplay/common.sh b/hotspot/test/compiler/ciReplay/common.sh index c7b656d26aa..261b0b81c0d 100644 --- a/hotspot/test/compiler/ciReplay/common.sh +++ b/hotspot/test/compiler/ciReplay/common.sh @@ -263,10 +263,10 @@ generate_replay() { dir=`dirname $core_with_dir` file=`basename $core_with_dir` # add /core. core - core_locations="'$core_with_dir' '$file'" + core_locations='$core_with_dir' '$file' if [ -n "${core_with_pid}" ] then - core_locations="$core_locations '$core_with_pid' '$dir${FS}$core_with_pid'" + core_locations=$core_locations '$core_with_pid' '$dir${FS}$core_with_pid' fi fi From 5ed29142e5abde94640b9b3bac53c2f05cb576fa Mon Sep 17 00:00:00 2001 From: Pavel Chistyakov Date: Tue, 23 Dec 2014 16:36:44 +0300 Subject: [PATCH 09/72] 8066896: Update c.o.j.t.InfiniteLoop to skip zero timeout Reviewed-by: kvn, iignatyev --- .../testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java index 9c52dcaa12f..fde92a86049 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java @@ -54,7 +54,9 @@ public class InfiniteLoop implements Runnable { try { while (true) { target.run(); - Thread.sleep(mills); + if (mills > 0) { + Thread.sleep(mills); + } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); From c9213782f3353c5ca9dd179e46695d176cd79e93 Mon Sep 17 00:00:00 2001 From: Tatiana Pivovarova Date: Tue, 16 Dec 2014 17:26:42 +0300 Subject: [PATCH 10/72] 8067173: remove Utils::fileAsList Reviewed-by: kvn, iignatyev --- .../com/oracle/java/testlibrary/Utils.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java index ef571a0960b..6a3df428525 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java @@ -306,25 +306,6 @@ public final class Utils { } } - /** - * Returns file content as a list of strings - * - * @param file File to operate on - * @return List of strings - * @throws IOException - */ - public static List fileAsList(File file) throws IOException { - assertTrue(file.exists() && file.isFile(), - file.getAbsolutePath() + " does not exist or not a file"); - List output = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) { - while (reader.ready()) { - output.add(reader.readLine().replace(NEW_LINE, "")); - } - } - return output; - } - /** * Return the contents of the named file as a single String, * or null if not found. From 2e085fa4b3159cdbadf146211563721907bba541 Mon Sep 17 00:00:00 2001 From: Evgeniya Stepanova Date: Tue, 23 Dec 2014 12:40:13 +0300 Subject: [PATCH 11/72] 8066864: remove ctw-test from testlibrary/ Reviewed-by: kvn, iignatyev --- hotspot/test/testlibrary/ctw/test/Bar.java | 5 - .../testlibrary/ctw/test/ClassesDirTest.java | 62 --------- .../testlibrary/ctw/test/ClassesListTest.java | 59 --------- .../test/testlibrary/ctw/test/CtwTest.java | 118 ------------------ hotspot/test/testlibrary/ctw/test/Foo.java | 5 - .../test/testlibrary/ctw/test/JarDirTest.java | 76 ----------- .../test/testlibrary/ctw/test/JarsTest.java | 66 ---------- hotspot/test/testlibrary/ctw/test/classes.lst | 4 - 8 files changed, 395 deletions(-) delete mode 100644 hotspot/test/testlibrary/ctw/test/Bar.java delete mode 100644 hotspot/test/testlibrary/ctw/test/ClassesDirTest.java delete mode 100644 hotspot/test/testlibrary/ctw/test/ClassesListTest.java delete mode 100644 hotspot/test/testlibrary/ctw/test/CtwTest.java delete mode 100644 hotspot/test/testlibrary/ctw/test/Foo.java delete mode 100644 hotspot/test/testlibrary/ctw/test/JarDirTest.java delete mode 100644 hotspot/test/testlibrary/ctw/test/JarsTest.java delete mode 100644 hotspot/test/testlibrary/ctw/test/classes.lst diff --git a/hotspot/test/testlibrary/ctw/test/Bar.java b/hotspot/test/testlibrary/ctw/test/Bar.java deleted file mode 100644 index 9b0324555f8..00000000000 --- a/hotspot/test/testlibrary/ctw/test/Bar.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Bar { - private static void staticMethod() { } - public void method() { } - protected Bar() { } -} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java deleted file mode 100644 index 656f36438c6..00000000000 --- a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main ClassesDirTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes - * @run main ClassesDirTest check ctw.log - * @summary testing of CompileTheWorld :: classes in directory - * @author igor.ignatyev@oracle.com - */ - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class ClassesDirTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# dir: classes", "Done (2 classes, 6 methods, "}; - - private ClassesDirTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new ClassesDirTest().run(args); - } - - protected void prepare() throws Exception { - String path = "classes"; - Files.createDirectory(Paths.get(path)); - Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"), - StandardCopyOption.REPLACE_EXISTING); - Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"), - StandardCopyOption.REPLACE_EXISTING); - } -} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java deleted file mode 100644 index 8c92fb038a6..00000000000 --- a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main ClassesListTest prepare - * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst - * @run main ClassesListTest check ctw.log - * @summary testing of CompileTheWorld :: list of classes in file - * @author igor.ignatyev@oracle.com - */ - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class ClassesListTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# list: classes.lst", "Done (4 classes, "}; - - private ClassesListTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new ClassesListTest().run(args); - } - - protected void prepare() throws Exception { - String path = "classes.lst"; - Files.copy(Paths.get(System.getProperty("test.src"), path), - Paths.get(path), StandardCopyOption.REPLACE_EXISTING); - } -} diff --git a/hotspot/test/testlibrary/ctw/test/CtwTest.java b/hotspot/test/testlibrary/ctw/test/CtwTest.java deleted file mode 100644 index ecc9c59c13a..00000000000 --- a/hotspot/test/testlibrary/ctw/test/CtwTest.java +++ /dev/null @@ -1,118 +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.List; -import java.util.Collections; -import java.util.ArrayList; - -import java.io.File; -import java.io.Writer; -import java.io.FileWriter; -import java.io.IOException; -import java.io.BufferedReader; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.nio.charset.Charset; - -import com.oracle.java.testlibrary.JDKToolFinder; -import com.oracle.java.testlibrary.OutputAnalyzer; - -public abstract class CtwTest { - protected final String[] shouldContain; - protected CtwTest(String[] shouldContain) { - this.shouldContain = shouldContain; - } - - public void run(String[] args) throws Exception { - if (args.length == 0) { - throw new Error("args is empty"); - } - switch (args[0]) { - case "prepare": - prepare(); - break; - case "check": - check(args); - break; - default: - throw new Error("unregonized action -- " + args[0]); - } - } - - protected void prepare() throws Exception { } - - protected void check(String[] args) throws Exception { - if (args.length < 2) { - throw new Error("logfile isn't specified"); - } - String logfile = args[1]; - try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile), - Charset.defaultCharset())) { - OutputAnalyzer output = readOutput(r); - for (String test : shouldContain) { - output.shouldContain(test); - } - } - } - - private static OutputAnalyzer readOutput(BufferedReader reader) - throws IOException { - StringBuilder builder = new StringBuilder(); - String eol = String.format("%n"); - String line; - - while ((line = reader.readLine()) != null) { - builder.append(line); - builder.append(eol); - } - return new OutputAnalyzer(builder.toString(), ""); - } - - protected void dump(OutputAnalyzer output, String name) { - try (Writer w = new FileWriter(name + ".out")) { - String s = output.getStdout(); - w.write(s, s.length(), 0); - } catch (IOException io) { - io.printStackTrace(); - } - try (Writer w = new FileWriter(name + ".err")) { - String s = output.getStderr(); - w.write(s, s.length(), 0); - } catch (IOException io) { - io.printStackTrace(); - } - } - - protected ProcessBuilder createJarProcessBuilder(String... command) - throws Exception { - String javapath = JDKToolFinder.getJDKTool("jar"); - - ArrayList args = new ArrayList<>(); - args.add(javapath); - Collections.addAll(args, command); - - return new ProcessBuilder(args.toArray(new String[args.size()])); - } -} diff --git a/hotspot/test/testlibrary/ctw/test/Foo.java b/hotspot/test/testlibrary/ctw/test/Foo.java deleted file mode 100644 index 07d8f4643ce..00000000000 --- a/hotspot/test/testlibrary/ctw/test/Foo.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Foo { - private static void staticMethod() { } - public void method() { } - protected Foo() { } -} diff --git a/hotspot/test/testlibrary/ctw/test/JarDirTest.java b/hotspot/test/testlibrary/ctw/test/JarDirTest.java deleted file mode 100644 index fef89f8dd8d..00000000000 --- a/hotspot/test/testlibrary/ctw/test/JarDirTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main JarDirTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/* - * @run main JarDirTest check ctw.log - * @summary testing of CompileTheWorld :: jars in directory - * @author igor.ignatyev@oracle.com - */ - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; - -import com.oracle.java.testlibrary.OutputAnalyzer; - -public class JarDirTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# jar_in_dir: jars", - "# jar: jars" + File.separator +"foo.jar", - "# jar: jars" + File.separator +"bar.jar", - "Done (4 classes, 12 methods, "}; - - private JarDirTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new JarDirTest().run(args); - } - - protected void prepare() throws Exception { - String path = "jars"; - Files.createDirectory(Paths.get(path)); - - ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar", - "Foo.class", "Bar.class"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-foo.jar"); - output.shouldHaveExitValue(0); - - pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class", - "Bar.class"); - output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-bar.jar"); - output.shouldHaveExitValue(0); - } - -} diff --git a/hotspot/test/testlibrary/ctw/test/JarsTest.java b/hotspot/test/testlibrary/ctw/test/JarsTest.java deleted file mode 100644 index 277cc1f808a..00000000000 --- a/hotspot/test/testlibrary/ctw/test/JarsTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main JarsTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar - * @run main JarsTest check ctw.log - * @summary testing of CompileTheWorld :: jars - * @author igor.ignatyev@oracle.com - */ - -import com.oracle.java.testlibrary.OutputAnalyzer; - -public class JarsTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# jar: foo.jar", "# jar: bar.jar", - "Done (4 classes, 12 methods, "}; - - private JarsTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new JarsTest().run(args); - } - - protected void prepare() throws Exception { - ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar", - "Foo.class", "Bar.class"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-foo.jar"); - output.shouldHaveExitValue(0); - - pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class"); - output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-bar.jar"); - output.shouldHaveExitValue(0); - } - -} diff --git a/hotspot/test/testlibrary/ctw/test/classes.lst b/hotspot/test/testlibrary/ctw/test/classes.lst deleted file mode 100644 index 044c029e783..00000000000 --- a/hotspot/test/testlibrary/ctw/test/classes.lst +++ /dev/null @@ -1,4 +0,0 @@ -java.lang.String -java.lang.Object -Foo -Bar From 80613b8656c330c6ee23a40c8458ade3e2beaac2 Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Wed, 24 Dec 2014 19:32:13 +0300 Subject: [PATCH 12/72] 8068183: Add isTieredSupported method to c.o.j.t.Platforms Reviewed-by: kvn, iignatyev --- .../com/oracle/java/testlibrary/Platform.java | 5 ++ ...stMutuallyExclusivePlatformPredicates.java | 2 +- .../TestPlatformIsTieredSupported.java | 49 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java index 4553d0d2184..8bdb863ed46 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java @@ -34,6 +34,7 @@ public class Platform { private static final String osArch = System.getProperty("os.arch"); private static final String vmName = System.getProperty("java.vm.name"); private static final String userName = System.getProperty("user.name"); + private static final String compiler = System.getProperty("sun.management.compiler"); public static boolean isClient() { return vmName.endsWith(" Client VM"); @@ -55,6 +56,10 @@ public class Platform { return vmName.contains("Embedded"); } + public static boolean isTieredSupported() { + return compiler.contains("Tiered Compilers"); + } + public static boolean is32bit() { return dataModel.equals("32"); } diff --git a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java index be8d04ff022..b16d6eb7540 100644 --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java @@ -48,7 +48,7 @@ public class TestMutuallyExclusivePlatformPredicates { OS("isLinux", "isSolaris", "isWindows", "isOSX"), VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"), IGNORED("isEmbedded", "isDebugBuild", "shouldSAAttach", - "canPtraceAttachLinux", "canAttachOSX"); + "canPtraceAttachLinux", "canAttachOSX", "isTieredSupported"); public final List methodNames; diff --git a/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java new file mode 100644 index 00000000000..9caa869c29a --- /dev/null +++ b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import sun.hotspot.WhiteBox; + +/** + * @test + * @summary Verifies that Platform::isTieredSupported returns correct value. + * @library /testlibrary /../../test/lib + * @build TestPlatformIsTieredSupported + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * TestPlatformIsTieredSupported + */ +public class TestPlatformIsTieredSupported { + public static void main(String args[]) { + WhiteBox whiteBox = WhiteBox.getWhiteBox(); + boolean tieredCompilation = whiteBox.getBooleanVMFlag( + "TieredCompilation"); + Asserts.assertEQ(Platform.isTieredSupported(), tieredCompilation, + "Platform::isTieredSupported should report the same value as " + + "TieredCompilation flag's value when " + + "+TieredCompilation was explicitly passed to JVM."); + } +} From f70b5b2e9c550c6e889b1ba5bef3e83d566bd0ab Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Fri, 26 Dec 2014 14:33:23 +0300 Subject: [PATCH 13/72] 8059623: JEP-JDK-8043304: Test task: command line options tests Reviewed-by: twisti, thartmann, goetz, iignatyev --- .../cli/TestSegmentedCodeCacheOption.java | 182 ++++++++++++++++++ .../CodeCacheFreeSpaceRunner.java | 62 ++++++ .../GenericCodeHeapSizeRunner.java | 72 +++++++ .../cli/codeheapsize/JVMStartupRunner.java | 133 +++++++++++++ .../codeheapsize/TestCodeHeapSizeOptions.java | 80 ++++++++ .../cli/common/CodeCacheCLITestBase.java | 61 ++++++ .../cli/common/CodeCacheCLITestCase.java | 165 ++++++++++++++++ .../cli/common/CodeCacheInfoFormatter.java | 79 ++++++++ .../cli/common/CodeCacheOptions.java | 129 +++++++++++++ .../printcodecache/PrintCodeCacheRunner.java | 87 +++++++++ .../TestPrintCodeCacheOption.java | 73 +++++++ 11 files changed, 1123 insertions(+) create mode 100644 hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java create mode 100644 hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java create mode 100644 hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java create mode 100644 hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java create mode 100644 hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java create mode 100644 hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java create mode 100644 hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java create mode 100644 hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java create mode 100644 hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java create mode 100644 hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java create mode 100644 hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java diff --git a/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java new file mode 100644 index 00000000000..525327a45cc --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * @test + * @bug 8015774 + * @summary Verify SegmentedCodeCache option's processing + * @library /testlibrary /../../test/lib + * @build TestSegmentedCodeCacheOption com.oracle.java.testlibrary.* + * @run main TestSegmentedCodeCacheOption + */ +public class TestSegmentedCodeCacheOption { + private static final String INT_MODE = "-Xint"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String USE_SEGMENTED_CODE_CACHE + = CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + true); + private static final long THRESHOLD_CC_SIZE_VALUE + = CodeCacheOptions.mB(240); + private static final long BELOW_THRESHOLD_CC_SIZE + = THRESHOLD_CC_SIZE_VALUE - CodeCacheOptions.mB(1); + private static final String[] UNEXPECTED_MESSAGES = new String[] { + ".*" + SEGMENTED_CODE_CACHE + ".*" + }; + + + private static enum TestCase { + JVM_STARTUP { + @Override + public void run() throws Throwable { + // There should be no errors when we're trying to enable SCC ... + String testCaseWarningMessage = "JVM output should not contain " + + "any warnings related to " + SEGMENTED_CODE_CACHE; + String testCaseExitCodeMessage = "JVM should start without any " + + "issues with " + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE); + // ... and when we're trying to enable it w/o TieredCompilation + testCaseExitCodeMessage = "Disabled tiered compilation should " + + "not cause startup failure w/ " + + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // ... and even w/ Xint. + testCaseExitCodeMessage = "It should be possible to use " + + USE_SEGMENTED_CODE_CACHE + " in interpreted mode " + + "without any errors."; + + CommandLineOptionTest.verifyJVMStartup( + /* expected messages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, false, INT_MODE, USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_GENERIC { + @Override + public void run() throws Throwable { + // SCC is disabled w/o TieredCompilation by default + String errorMessage = SEGMENTED_CODE_CACHE + + " should be disabled by default when tiered " + + "compilation is disabled"; + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // SCC is disabled by default when ReservedCodeCacheSize is too + // small + errorMessage = String.format("%s should be disabled bu default " + + "when %s value is too small.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE)); + // SCC could be explicitly enabled w/ Xint + errorMessage = String.format("It should be possible to " + + "explicitly enable %s in interpreted mode.", + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValue(SEGMENTED_CODE_CACHE, + "true", errorMessage, false, INT_MODE, + USE_SEGMENTED_CODE_CACHE); + // SCC could be explicitly enabled w/o TieredCompilation and w/ + // small ReservedCodeCacheSize value + errorMessage = String.format("It should be possible to " + + "explicitly enable %s with small %s and " + + "disabled tiered comp.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE), + USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_SERVER_SPECIFIC { + @Override + public boolean isApplicable() { + return Platform.isServer() && Platform.isTieredSupported(); + } + + @Override + public void run() throws Throwable { + // SCC is enabled by default when TieredCompilation is on and + // ReservedCodeCacheSize is large enough + String errorMessage = String.format("Large enough %s and " + + "enabled tiered compilation should enable %s " + + "by default.", BlobType.All.sizeOptionName, + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + THRESHOLD_CC_SIZE_VALUE), + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, true)); + } + }; + + TestCase() { + } + + public boolean isApplicable() { + return true; + } + + public abstract void run() throws Throwable; + } + + public static void main(String args[]) throws Throwable { + for (TestCase testCase : TestCase.values()) { + if (testCase.isApplicable()) { + System.out.println("Running test case: " + testCase.name()); + testCase.run(); + } else { + System.out.println("Test case skipped: " + testCase.name()); + } + } + } +} diff --git a/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java b/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java new file mode 100644 index 00000000000..dcfc437ddf3 --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that NonNMethodCodeHeapSize smaller than + * CodeCacheMinimumUseSpace cause JVM startup failure. + */ +public class CodeCacheFreeSpaceRunner implements CodeCacheCLITestCase.Runner { + private static final String CC_MIN_USE_SPACE = "CodeCacheMinimumUseSpace"; + private static final String TOO_SMALL_NMETHOD_CH_ERROR + = "Invalid NonNMethodCodeHeapSize.*"; + private static final long MULTIPLIER = Platform.isDebugBuild() ? 3L : 1L; + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + long ccMinUseSpace = ((options.nonNmethods - 1) / MULTIPLIER + 1); + + String exitCodeErrorMessage = String.format("JVM startup should fail " + + "if %s's value lower then %s.", + BlobType.NonNMethod.sizeOptionName, CC_MIN_USE_SPACE); + String vmOutputErrorMessage = String.format("JVM's output should " + + "contain appropriate error message when %s lower " + + "then %s.", BlobType.NonNMethod.sizeOptionName, + CC_MIN_USE_SPACE); + + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ TOO_SMALL_NMETHOD_CH_ERROR }, + /* unexpected messages */ null, + exitCodeErrorMessage, vmOutputErrorMessage, ExitCode.FAIL, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareNumericFlag( + CC_MIN_USE_SPACE, ccMinUseSpace + 1))); + } +} diff --git a/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java b/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java new file mode 100644 index 00000000000..556bc9831c5 --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that all four options related to code cache + * sizing have correct values. + */ +public class GenericCodeHeapSizeRunner implements CodeCacheCLITestCase.Runner { + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = options.mapOptions(testCaseDescription.involvedCodeHeaps); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.All.sizeOptionName, + Long.toString(expectedValues.reserved), + String.format("%s should have value %d.", + BlobType.All.sizeOptionName, expectedValues.reserved), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.NonNMethod.sizeOptionName, + Long.toString(expectedValues.nonNmethods), + String.format("%s should have value %d.", + BlobType.NonNMethod.sizeOptionName, + expectedValues.nonNmethods), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodNonProfiled.sizeOptionName, + Long.toString(expectedValues.nonProfiled), + String.format("%s should have value %d.", + BlobType.MethodNonProfiled.sizeOptionName, + expectedValues.nonProfiled), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodProfiled.sizeOptionName, + Long.toString(expectedValues.profiled), + String.format("%s should have value %d.", + BlobType.MethodProfiled.sizeOptionName, + expectedValues.profiled), + testCaseDescription.getTestOptions(options)); + } +} diff --git a/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java b/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java new file mode 100644 index 00000000000..03853b670d5 --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; +import java.util.Random; + +/** + * Test case runner aimed to verify option's consistency. + */ +public class JVMStartupRunner implements CodeCacheCLITestCase.Runner { + private static final String INCONSISTENT_CH_SIZES_ERROR + = "Invalid code heap sizes.*"; + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + // Everything should be fine when + // sum(all code heap sizes) == reserved CC size + CommandLineOptionTest.verifySameJVMStartup(/* expected messages */ null, + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + "JVM startup should not fail with consistent code heap sizes", + "JVM output should not contain warning about inconsistent code " + + "heap sizes", ExitCode.OK, options.prepareOptions()); + + verifySingleInconsistentValue(options); + verifyAllInconsistentValues(options); + } + + /** + * Verifies that if at least one of three options will have value, such + * that sum of all three values will be inconsistent, then JVM startup will + * fail. + */ + private static void verifySingleInconsistentValue(CodeCacheOptions options) + throws Throwable { + verifyHeapSizesSum(options.reserved, + scaleCodeHeapSize(options.profiled), options.nonProfiled, + options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + scaleCodeHeapSize(options.nonProfiled), options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + options.nonProfiled, scaleCodeHeapSize(options.nonNmethods)); + } + + /** + * Verifies that if all three options will have values such that their sum + * is inconsistent with ReservedCodeCacheSize value, then JVM startup will + * fail. + */ + private static void verifyAllInconsistentValues(CodeCacheOptions options) + throws Throwable { + long profiled = options.profiled; + long nonProfiled = options.nonProfiled; + long nonNMethods = options.nonNmethods; + + while (options.reserved == profiled + nonProfiled + nonNMethods) { + profiled = scaleCodeHeapSize(profiled); + nonProfiled = scaleCodeHeapSize(nonProfiled); + nonNMethods = scaleCodeHeapSize(nonNMethods); + } + + verifyHeapSizesSum(options.reserved, profiled, nonProfiled, + nonNMethods); + } + + private static void verifyHeapSizesSum(long reserved, long profiled, + long nonProfiled, long nonNmethods) throws Throwable { + // JVM startup expected to fail when + // sum(all code heap sizes) != reserved CC size + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + /* unexpected messages */ null, + "JVM startup should fail with inconsistent code heap size.", + "JVM output should contain appropriate error message of code " + + "heap sizes are inconsistent", + ExitCode.FAIL, + CommandLineOptionTest.prepareBooleanFlag( + CodeCacheOptions.SEGMENTED_CODE_CACHE, true), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods)); + } + + /** + * Returns {@code unscaledSize} value scaled by a random factor from + * range (1, 2). If {@code unscaledSize} is not 0, then this + * method will return value that won't be equal to {@code unscaledSize}. + * + * @param unscaledSize The value to be scaled. + * @return {@code unscaledSize} value scaled by a factor from range (1, 2). + */ + private static long scaleCodeHeapSize(long unscaledSize) { + Random random = Utils.getRandomInstance(); + + long scaledSize = unscaledSize; + while (scaledSize == unscaledSize && unscaledSize != 0) { + float scale = 1.0f + random.nextFloat(); + scaledSize = (long) Math.ceil(scale * unscaledSize); + } + return scaledSize; + } +} diff --git a/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java new file mode 100644 index 00000000000..e1253598e1b --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.Platform; +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @bug 8015774 + * @summary Verify processing of options related to code heaps sizing. + * @library /testlibrary .. /../../test/lib + * @build TestCodeHeapSizeOptions com.oracle.java.testlibrary.* codeheapsize.* + * common.* + * @run main/timeout=240 codeheapsize.TestCodeHeapSizeOptions + */ +public class TestCodeHeapSizeOptions extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase JVM_STARTUP + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented, + EnumSet.noneOf(BlobType.class)), + new JVMStartupRunner()); + + private static final CodeCacheCLITestCase CODE_CACHE_FREE_SPACE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented + && Platform.isDebugBuild(), + EnumSet.noneOf(BlobType.class)), + new CodeCacheFreeSpaceRunner()); + + private static final GenericCodeHeapSizeRunner GENERIC_RUNNER + = new GenericCodeHeapSizeRunner(); + + private TestCodeHeapSizeOptions() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + GENERIC_RUNNER), + JVM_STARTUP, + CODE_CACHE_FREE_SPACE); + } + + public static void main(String args[]) throws Throwable { + new TestCodeHeapSizeOptions().runTestCases(); + } +} diff --git a/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java new file mode 100644 index 00000000000..d57e0f7045c --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +/** + * Base for code cache related command line options tests. + */ +public class CodeCacheCLITestBase { + public static final CodeCacheOptions[] OPTIONS_SET + = new CodeCacheOptions[] { + new CodeCacheOptions(CodeCacheOptions.mB(60), + CodeCacheOptions.mB(20), CodeCacheOptions.mB(20), + CodeCacheOptions.mB(20)), + new CodeCacheOptions(CodeCacheOptions.mB(200), + CodeCacheOptions.mB(75), CodeCacheOptions.mB(75), + CodeCacheOptions.mB(50)), + new CodeCacheOptions(CodeCacheOptions.mB(300), + CodeCacheOptions.mB(100), CodeCacheOptions.mB(100), + CodeCacheOptions.mB(100)), + new CodeCacheOptions(CodeCacheOptions.mB(60)), + new CodeCacheOptions(CodeCacheOptions.mB(200)), + new CodeCacheOptions(CodeCacheOptions.mB(300)) + }; + + private final CodeCacheCLITestCase[] testCases; + private final CodeCacheOptions[] options; + + public CodeCacheCLITestBase(CodeCacheOptions[] options, + CodeCacheCLITestCase... testCases) { + this.testCases = testCases; + this.options = options; + } + + protected void runTestCases() throws Throwable { + for (CodeCacheCLITestCase testCase : testCases) { + for (CodeCacheOptions opts : options) { + testCase.run(opts); + } + } + } +} diff --git a/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java new file mode 100644 index 00000000000..ee40cb2492b --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Function; + +/** + * Code cache related command line option test case consisting of description + * of code heaps used during test case run and additional options that should + * be passed to JVM and runner aimed to perform actual testing based on the + * description. + */ +public class CodeCacheCLITestCase { + private static final Function ONLY_SEGMENTED + = options -> options.segmented; + private static final Function SEGMENTED_SERVER + = ONLY_SEGMENTED.andThen(isSegmented -> isSegmented + && Platform.isServer() && Platform.isTieredSupported()); + private static final String USE_INT_MODE = "-Xint"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String TIERED_STOP_AT = "TieredStopAtLevel"; + + private final Description description; + private final Runner runner; + + public CodeCacheCLITestCase(Description description, Runner runner) { + this.description = description; + this.runner = runner; + } + + public final void run(CodeCacheOptions options) throws Throwable { + if (description.isApplicable(options)) { + runner.run(description, options); + } + } + + public enum CommonDescriptions { + /** + * Verifies that in interpreted mode PrintCodeCache output contains + * only NonNMethod code heap. + */ + INT_MODE(ONLY_SEGMENTED, EnumSet.of(BlobType.NonNMethod), USE_INT_MODE), + /** + * Verifies that with disabled SegmentedCodeCache PrintCodeCache output + * contains only CodeCache's entry. + */ + NON_SEGMENTED(options -> !options.segmented, EnumSet.of(BlobType.All), + CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + false)), + /** + * Verifies that with disabled tiered compilation and enabled segmented + * code cache PrintCodeCache output does not contain information about + * profiled-nmethods heap and non-segmented CodeCache. + */ + NON_TIERED(ONLY_SEGMENTED, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + false)), + /** + * Verifies that with TieredStopAtLevel=0 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_0(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 0)), + /** + * Verifies that with TieredStopAtLevel=1 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_1(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 1)), + /** + * Verifies that with TieredStopAtLevel=4 PrintCodeCache output will + * contain information about all three code heaps. + */ + TIERED_LEVEL_4(SEGMENTED_SERVER, + EnumSet.complementOf(EnumSet.of(BlobType.All)), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 4)); + + CommonDescriptions(Function predicate, + EnumSet involvedCodeHeaps, + String... additionalOptions) { + this.description = new Description(predicate, + involvedCodeHeaps, additionalOptions); + } + + + public final Description description; + } + + public static class Description { + public final EnumSet involvedCodeHeaps; + private final String[] testCaseSpecificOptions; + private final Function predicate; + + public Description(Function predicate, + EnumSet involvedCodeHeaps, + String... testCaseSpecificOptions) { + this.involvedCodeHeaps = involvedCodeHeaps; + this.testCaseSpecificOptions = testCaseSpecificOptions; + this.predicate = predicate; + } + + public boolean isApplicable(CodeCacheOptions options) { + return predicate.apply(options); + } + + public CodeCacheOptions expectedValues(CodeCacheOptions options) { + return options.mapOptions(involvedCodeHeaps); + } + + public String[] getTestOptions(CodeCacheOptions codeCacheOptions, + String... additionalOptions) { + List options = new LinkedList<>(); + Collections.addAll(options, testCaseSpecificOptions); + Collections.addAll(options, additionalOptions); + return codeCacheOptions.prepareOptions( + options.toArray(new String[options.size()])); + } + } + + public static interface Runner { + public void run(Description testCaseDescription, + CodeCacheOptions options) throws Throwable; + } +} + diff --git a/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java b/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java new file mode 100644 index 00000000000..3ad16a6d733 --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import sun.hotspot.code.BlobType; +import java.util.Arrays; + +public class CodeCacheInfoFormatter { + private static final String DEFAULT_SIZE_FORMAT = "[0-9]+Kb"; + private BlobType heap = null; + private String size = DEFAULT_SIZE_FORMAT; + private String used = DEFAULT_SIZE_FORMAT; + private String maxUsed = DEFAULT_SIZE_FORMAT; + private String free = DEFAULT_SIZE_FORMAT; + + public static CodeCacheInfoFormatter forHeap(BlobType heap) { + return new CodeCacheInfoFormatter(heap); + } + + public static String[] forHeaps(BlobType... heaps) { + return Arrays.stream(heaps) + .map(CodeCacheInfoFormatter::forHeap) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + } + + private static String formatSize(long suffix) { + return String.format("%dKb", suffix / 1024); + } + + private CodeCacheInfoFormatter(BlobType heap) { + this.heap = heap; + } + + public CodeCacheInfoFormatter withSize(long size) { + this.size = CodeCacheInfoFormatter.formatSize(size); + return this; + } + + public CodeCacheInfoFormatter withUsed(long used) { + this.used = CodeCacheInfoFormatter.formatSize(used); + return this; + } + + public CodeCacheInfoFormatter withMaxUsed(long maxUsed) { + this.maxUsed = CodeCacheInfoFormatter.formatSize(maxUsed); + return this; + } + + public CodeCacheInfoFormatter withFree(long free) { + this.free = CodeCacheInfoFormatter.formatSize(free); + return this; + } + + public String getInfoString() { + return String.format("%s: size=%s used=%s max_used=%s free=%s", + heap.beanName, size, used, maxUsed, free); + } +} diff --git a/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java b/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java new file mode 100644 index 00000000000..e8b2bca35b5 --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; + +public class CodeCacheOptions { + public static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + + private static final EnumSet NON_SEGMENTED_HEAPS + = EnumSet.of(BlobType.All); + private static final EnumSet ALL_SEGMENTED_HEAPS + = EnumSet.complementOf(NON_SEGMENTED_HEAPS); + private static final EnumSet SEGMENTED_HEAPS_WO_PROFILED + = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled); + private static final EnumSet ONLY_NON_METHODS_HEAP + = EnumSet.of(BlobType.NonNMethod); + + public final long reserved; + public final long nonNmethods; + public final long nonProfiled; + public final long profiled; + public final boolean segmented; + + public static long mB(long val) { + return CodeCacheOptions.kB(val) * 1024L; + } + + public static long kB(long val) { + return val * 1024L; + } + + public CodeCacheOptions(long reserved) { + this.reserved = reserved; + this.nonNmethods = 0; + this.nonProfiled = 0; + this.profiled = 0; + this.segmented = false; + } + + public CodeCacheOptions(long reserved, long nonNmethods, long nonProfiled, + long profiled) { + this.reserved = reserved; + this.nonNmethods = nonNmethods; + this.nonProfiled = nonProfiled; + this.profiled = profiled; + this.segmented = true; + } + + public long sizeForHeap(BlobType heap) { + switch (heap) { + case All: + return this.reserved; + case NonNMethod: + return this.nonNmethods; + case MethodNonProfiled: + return this.nonProfiled; + case MethodProfiled: + return this.profiled; + default: + throw new Error("Unknown heap: " + heap.name()); + } + } + + public String[] prepareOptions(String... additionalOptions) { + List options = new ArrayList<>(); + Collections.addAll(options, additionalOptions); + Collections.addAll(options, + CommandLineOptionTest.prepareBooleanFlag( + SEGMENTED_CODE_CACHE, segmented), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved)); + + if (segmented) { + Collections.addAll(options, + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, + nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled)); + } + return options.toArray(new String[options.size()]); + } + + public CodeCacheOptions mapOptions(EnumSet involvedCodeHeaps) { + if (involvedCodeHeaps.isEmpty() + || involvedCodeHeaps.equals(NON_SEGMENTED_HEAPS) + || involvedCodeHeaps.equals(ALL_SEGMENTED_HEAPS)) { + return this; + } else if (involvedCodeHeaps.equals(SEGMENTED_HEAPS_WO_PROFILED)) { + return new CodeCacheOptions(reserved, nonNmethods, + profiled + nonProfiled, 0L); + } else if (involvedCodeHeaps.equals(ONLY_NON_METHODS_HEAP)) { + return new CodeCacheOptions(reserved, nonNmethods + profiled + + nonProfiled, 0L, 0L); + } else { + throw new Error("Test bug: unexpected set of code heaps involved " + + "into test."); + } + } +} diff --git a/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java new file mode 100644 index 00000000000..74b21f1f19e --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package printcodecache; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheInfoFormatter; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +import java.util.EnumSet; +import java.util.stream.Collectors; + +/** + * Runner implementation aimed to verify PrintCodeCache output. + */ +public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner { + private final boolean printCodeCache; + + public PrintCodeCacheRunner(boolean printCodeCache) { + this.printCodeCache = printCodeCache; + } + + public PrintCodeCacheRunner() { + this(true); + } + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = testCaseDescription.expectedValues(options); + + String[] expectedMessages + = testCaseDescription.involvedCodeHeaps.stream() + .map(heap -> CodeCacheInfoFormatter.forHeap(heap) + .withSize(expectedValues.sizeForHeap(heap))) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + + EnumSet unexpectedHeapsSet + = EnumSet.complementOf(testCaseDescription.involvedCodeHeaps); + + String[] unexpectedMessages = CodeCacheInfoFormatter.forHeaps( + unexpectedHeapsSet.toArray( + new BlobType[unexpectedHeapsSet.size()])); + + String description = String.format("JVM output should contain entries " + + "for following code heaps: [%s] and should not contain " + + "entries for following code heaps: [%s].", + testCaseDescription.involvedCodeHeaps.stream() + .map(BlobType::name) + .collect(Collectors.joining(", ")), + unexpectedHeapsSet.stream() + .map(BlobType::name) + .collect(Collectors.joining(", "))); + + CommandLineOptionTest.verifySameJVMStartup(expectedMessages, + unexpectedMessages, "JVM startup failure is not expected, " + + "since all options have allowed values", description, + ExitCode.OK, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareBooleanFlag( + "PrintCodeCache", printCodeCache))); + } +} diff --git a/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java new file mode 100644 index 00000000000..ae42251c77c --- /dev/null +++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package printcodecache; + +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @bug 8015774 + * @summary Verify that PrintCodeCache option print correct information. + * @library /testlibrary .. /../../test/lib + * @build TestPrintCodeCacheOption com.oracle.java.testlibrary.* + * printcodecache.* common.* + * @run main/timeout=240 printcodecache.TestPrintCodeCacheOption + */ +public class TestPrintCodeCacheOption extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase DISABLED_PRINT_CODE_CACHE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> true, EnumSet.noneOf(BlobType.class)), + new PrintCodeCacheRunner(false)); + + private static final CodeCacheCLITestCase.Runner DEFAULT_RUNNER + = new PrintCodeCacheRunner(); + + private TestPrintCodeCacheOption() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_SEGMENTED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + DEFAULT_RUNNER), + DISABLED_PRINT_CODE_CACHE); + } + + public static void main(String args[]) throws Throwable { + new TestPrintCodeCacheOption().runTestCases(); + } +} From 583d750b3df9d496b367f3aa7af154d4bbff5cfa Mon Sep 17 00:00:00 2001 From: Pavel Chistyakov Date: Fri, 26 Dec 2014 14:47:35 +0300 Subject: [PATCH 14/72] 8066497: Update c.o.j.t.ByteCodeLoader to be able really reload given class Reviewed-by: drchase, fzhinkin, iignatyev --- .../oracle/java/testlibrary/ByteCodeLoader.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java index 46309eae0ca..a79bd740622 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java @@ -37,6 +37,7 @@ import java.security.SecureClassLoader; public class ByteCodeLoader extends SecureClassLoader { private final String className; private final byte[] byteCode; + private volatile Class holder; /** * Creates a new {@code ByteCodeLoader} ready to load a class with the @@ -50,6 +51,21 @@ public class ByteCodeLoader extends SecureClassLoader { this.byteCode = byteCode; } + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (!name.equals(className)) { + return super.loadClass(name); + } + if (holder == null) { + synchronized(this) { + if (holder == null) { + holder = findClass(name); + } + } + } + return holder; + } + @Override protected Class findClass(String name) throws ClassNotFoundException { if (!name.equals(className)) { From ea23edb88a68b0dce3f4c2d453fc64983a7c0528 Mon Sep 17 00:00:00 2001 From: Dmitrij Pochepko Date: Thu, 25 Dec 2014 15:57:38 +0300 Subject: [PATCH 15/72] 8059625: JEP-JDK-8043304: Test task: DTrace- tests for segmented codecache feature Reviewed-by: sspitsyn, twisti, fzhinkin, iignatyev --- .../dtrace/SegmentedCodeCacheDtraceTest.java | 307 ++++++++++++++++++ .../SegmentedCodeCacheDtraceTestScript.d | 33 ++ .../SegmentedCodeCacheDtraceTestWorker.java | 113 +++++++ .../compiler/testlibrary/CompilerUtils.java | 61 ++++ .../dtrace/DtraceResultsAnalyzer.java | 29 ++ .../java/testlibrary/dtrace/DtraceRunner.java | 121 +++++++ 6 files changed, 664 insertions(+) create mode 100644 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java create mode 100644 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d create mode 100644 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java create mode 100644 hotspot/test/compiler/testlibrary/CompilerUtils.java create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java diff --git a/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java new file mode 100644 index 00000000000..9046392d5b3 --- /dev/null +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.JDKToolFinder; +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.dtrace.DtraceResultsAnalyzer; +import com.oracle.java.testlibrary.dtrace.DtraceRunner; +import java.io.IOException; +import java.lang.reflect.Executable; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/* + * @test SegmentedCodeCacheDtraceTest + * @bug 8015774 + * @requires os.family=="solaris" + * @library /testlibrary /compiler/testlibrary /../../test/lib + * @build SegmentedCodeCacheDtraceTestWorker + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * SegmentedCodeCacheDtraceTest + * @summary testing of dtrace for segmented code cache + */ +public class SegmentedCodeCacheDtraceTest { + + private static final String WORKER_CLASS_NAME + = SegmentedCodeCacheDtraceTestWorker.class.getName(); + private static final String JAVA_OPTS = " -XX:+DTraceMethodProbes " + + "-Xbootclasspath/a:" + System.getProperty("test.classes") + " " + + "-XX:+UnlockDiagnosticVMOptions " + + "-XX:+WhiteBoxAPI -XX:+SegmentedCodeCache " + + "-XX:CompileCommand=compileonly," + + WORKER_CLASS_NAME + "::* " + + " -classpath " + System.getProperty("test.class.path") + " " + + String.join(" ", Utils.getTestJavaOpts()); + private static final String DTRACE_SCRIPT + = "SegmentedCodeCacheDtraceTestScript.d"; + private static final List MLIST = + SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST; + private static final int WORKER_METHODS_COUNT = MLIST.size(); + + private void runTest(TestCombination tc) { + String params = MLIST.stream() + .map(Executable::getName) + .map(x -> tc.data.get(x).compileLevel + " " + tc.data.get(x).isInlined) + .collect(Collectors.joining(" ")); + DtraceRunner runner = new DtraceRunner(); + runner.runDtrace(JDKToolFinder.getTestJDKTool("java"), JAVA_OPTS, + WORKER_CLASS_NAME, params, Paths.get(System.getProperty("test.src"), + DTRACE_SCRIPT).toString(), + DtraceRunner.PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION, + new SegmentedCodeCacheDtraceResultsAnalyzer()); + } + + private static TestCombination generateUniqueCombination( + int[] availableLevels, Set combinations) { + int len = availableLevels.length; + /* first, check if we're out of combinations. */ + int maxCombinationsCount + = (1 << WORKER_METHODS_COUNT) + * (int) Math.pow(len, WORKER_METHODS_COUNT); + if (combinations.size() == maxCombinationsCount) { + return null; + } + Random r = Utils.getRandomInstance(); + while (combinations.size() < maxCombinationsCount) { + int levels[] = new int[WORKER_METHODS_COUNT]; + boolean inlines[] = new boolean[WORKER_METHODS_COUNT]; + for (int i = 0; i < WORKER_METHODS_COUNT; i++) { + levels[i] = availableLevels[r.nextInt(len)]; + inlines[i] = r.nextBoolean(); + } + TestCombination tc = new TestCombination(levels, inlines); + if (combinations.add(tc)) { + return tc; + } + } + return null; + } + + public static void main(String args[]) { + int iterations + = Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + if (!DtraceRunner.dtraceAvailable()) { + System.out.println("INFO: There is no dtrace avaiable. Skipping."); + return; + } + int[] availableLevels = CompilerUtils.getAvailableCompilationLevels(); + // adding one more entry(zero) for interpeter + availableLevels + = Arrays.copyOf(availableLevels, availableLevels.length + 1); + Set combinations = new HashSet<>(); + for (int i = 0; i < iterations; i++) { + TestCombination tc + = generateUniqueCombination(availableLevels, combinations); + if (tc == null) { + System.out.println("INFO: no more combinations available"); + return; + } else { + System.out.println("INFO: Running testcase for: " + tc); + new SegmentedCodeCacheDtraceTest().runTest(tc); + } + } + } + + private static class MethodData { + + public final int compileLevel; + public final boolean isInlined; + public final String name; + + public MethodData(String name, int compileLevel, boolean isInlined) { + this.name = name; + this.compileLevel = compileLevel; + this.isInlined = isInlined; + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof MethodData)) { + return false; + } + MethodData md = (MethodData) o; + return md.compileLevel == compileLevel + && md.isInlined == isInlined + && md.name.equals(name); + } + + @Override + public int hashCode() { + return 100 * name.hashCode() + 10 * compileLevel + (isInlined ? 1 : 0); + } + + @Override + public String toString() { + return name + " " + compileLevel + " " + isInlined; + } + } + + private static class TestCombination { + + private final Map data; + + public TestCombination(int compLevels[], boolean inlines[]) { + Map d = new HashMap<>(); + for (int i = 0; i < MLIST.size(); i++) { + d.put(MLIST.get(i).getName(), new MethodData(MLIST.get(i).getName(), + compLevels[i], inlines[i])); + } + data = Collections.unmodifiableMap(d); + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof TestCombination)) { + return false; + } + TestCombination second = (TestCombination) o; + return second.data.equals(data); + } + + @Override + public int hashCode() { + int sum = 0; + for (MethodData md : data.values()) { + sum += md.hashCode(); + } + return sum; + } + + private String getMethodDescString(MethodData md) { + return (md == null) + ? null + : String.format("Method %s compilation level %d and %s", + md.name, md.compileLevel, + md.isInlined ? "inlined" : "not inlined"); + } + + @Override + public String toString() { + return data.values().stream().map(m -> getMethodDescString(m)) + .collect(Collectors.joining(Utils.NEW_LINE, + "Combination: ", "")); + } + } + + private class SegmentedCodeCacheDtraceResultsAnalyzer + implements DtraceResultsAnalyzer { + + private static final int EXPECTED_MATCH_COUNT = 2; + + private final Pattern checkPattern; + + public SegmentedCodeCacheDtraceResultsAnalyzer() { + String workerClassRegExp = "\\s*" + WORKER_CLASS_NAME + "\\."; + String delimeter = "\\(\\)V\\*?" + workerClassRegExp; + String suffix = "test\\(\\)V\\*?" + workerClassRegExp + + "main\\(\\[Ljava\\/lang\\/String;\\)V"; + StringBuilder sb = new StringBuilder(workerClassRegExp); + // method order is important, so, going from list tail to head, + // accoring to call order representation in stacktrace + for (int i = MLIST.size() - 1; i > -1; i--) { + sb.append(MLIST.get(i).getName()).append(delimeter); + } + sb.append(suffix); + checkPattern = Pattern.compile(sb.toString()); + /* such pattern match should pass on a stacktrace like + CPU ID FUNCTION:NAME + 0 53573 __1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_:method-entry ustack: + + libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c + SegmentedCodeCacheDtraceTestWorker.baz()V* + SegmentedCodeCacheDtraceTestWorker.bar()V + SegmentedCodeCacheDtraceTestWorker.foo()V* + SegmentedCodeCacheDtraceTestWorker.test()V + SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V + 0xffffffff6b0004b8 + libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c + libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64 + libjvm.so`jni_CallStaticVoidMethod+0x508 + libjli.so`JavaMain+0x584 + libc.so.1`_lwp_start + jstack: + + libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c + SegmentedCodeCacheDtraceTestWorker.baz()V* + SegmentedCodeCacheDtraceTestWorker.bar()V + SegmentedCodeCacheDtraceTestWorker.foo()V* + SegmentedCodeCacheDtraceTestWorker.test()V + SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V + 0xffffffff6b0004b8 + libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c + libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64 + libjvm.so`jni_CallStaticVoidMethod+0x508 + libjli.so`JavaMain+0x584 + libc.so.1`_lwp_start + */ + } + + protected List loadLog(String dtraceOutFile) throws IOException { + return Files.readAllLines(Paths.get(dtraceOutFile)); + } + + @Override + public void analyze(OutputAnalyzer oa, String dtraceOutFilePath) { + oa.shouldHaveExitValue(0); + List dOut; + try { + dOut = loadLog(dtraceOutFilePath); + } catch (IOException e) { + throw new Error("Can't load log", e); + } + StringBuilder allDtraceOutput = new StringBuilder(); + for (String entry : dOut) { + allDtraceOutput.append(entry); + } + int matchCount = getMatchCount(allDtraceOutput.toString()); + Asserts.assertEQ(matchCount, EXPECTED_MATCH_COUNT, + "Unexpected output match amount. expected: " + + EXPECTED_MATCH_COUNT + " but found " + matchCount); + } + + protected int getMatchCount(String source) { + Matcher m = checkPattern.matcher(source); + int matchCount = 0; + while (m.find()) { + matchCount++; + } + return matchCount; + } + } +} diff --git a/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d new file mode 100644 index 00000000000..be89dbd7a9b --- /dev/null +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d @@ -0,0 +1,33 @@ +#!/usr/sbin/dtrace -s + +/* + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +*/ + +hotspot$target:::method-entry +/ copyinstr(arg3, arg4) == "baz" / +{ + printf("ustack:\n"); + ustack(50, 500); + printf("jstack:\n"); + jstack(); +} diff --git a/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java new file mode 100644 index 00000000000..84c5533063c --- /dev/null +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Utils; +import java.lang.reflect.Executable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import sun.hotspot.WhiteBox; + +public class SegmentedCodeCacheDtraceTestWorker { + + private static final String METHOD1_NAME = "foo"; + private static final String METHOD2_NAME = "bar"; + private static final String METHOD3_NAME = "baz"; + public static final List TESTED_METHODS_LIST; + private final WhiteBox wb; + private final int compLevels[]; + + static { + List methods = new ArrayList<>(); + try { + // method order is important. Need to place methods in call order, + // to be able to verify results later + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD1_NAME)); + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD2_NAME)); + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD3_NAME)); + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG: no expected method found", e); + } + TESTED_METHODS_LIST = Collections.unmodifiableList(methods); + } + + protected static final boolean BACKGROUND_COMPILATION + = WhiteBox.getWhiteBox().getBooleanVMFlag("BackgroundCompilation"); + + public static void main(String[] args) { + if (args.length != 2 * TESTED_METHODS_LIST.size()) { + throw new Error("Usage: java " + + " " + + " "); + } else { + int compLevels[] = new int[TESTED_METHODS_LIST.size()]; + boolean inlines[] = new boolean[TESTED_METHODS_LIST.size()]; + for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) { + compLevels[i] = Integer.parseInt(args[2 * i]); + inlines[i] = Boolean.parseBoolean(args[2 * i + 1]); + } + new SegmentedCodeCacheDtraceTestWorker(compLevels, inlines).test(); + } + } + + public SegmentedCodeCacheDtraceTestWorker(int compLevels[], boolean inlines[]) { + wb = WhiteBox.getWhiteBox(); + this.compLevels = Arrays.copyOf(compLevels, compLevels.length); + for (int i = 0; i < compLevels.length; i++) { + if (inlines[i]) { + wb.testSetForceInlineMethod(TESTED_METHODS_LIST.get(i), true); + } else { + wb.testSetDontInlineMethod(TESTED_METHODS_LIST.get(i), true); + } + } + } + + private void waitForCompilation(Executable executable, int compLevel) { + if (compLevel > 0) { + Utils.waitForCondition(() -> wb.isMethodCompiled(executable)); + } + } + + protected void test() { + for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) { + Executable method = TESTED_METHODS_LIST.get(i); + int compLevel = compLevels[i]; + wb.enqueueMethodForCompilation(method, compLevel); + waitForCompilation(method, compLevel); + } + foo(); + } + + public static void foo() { + bar(); + } + + public static void bar() { + baz(); + } + + public static void baz() { + System.out.println("Reached baz method"); + } +} diff --git a/hotspot/test/compiler/testlibrary/CompilerUtils.java b/hotspot/test/compiler/testlibrary/CompilerUtils.java new file mode 100644 index 00000000000..6da0c7c0fe1 --- /dev/null +++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import java.util.stream.IntStream; +import sun.hotspot.WhiteBox; + +public class CompilerUtils { + + private CompilerUtils() { + // to prevent from instantiation + } + + /** + * Returns available compilation levels + * + * @return int array with compilation levels + */ + public static int[] getAvailableCompilationLevels() { + if (!WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompiler")) { + return new int[0]; + } + if (WhiteBox.getWhiteBox().getBooleanVMFlag("TieredCompilation")) { + Long flagValue = WhiteBox.getWhiteBox() + .getIntxVMFlag("TieredStopAtLevel"); + int maxLevel = flagValue.intValue(); + Asserts.assertEQ(new Long(maxLevel), flagValue, + "TieredStopAtLevel has value out of int capacity"); + return IntStream.rangeClosed(1, maxLevel).toArray(); + } else { + if (Platform.isServer()) { + return new int[]{4}; + } + if (Platform.isClient() || Platform.isMinimal()) { + return new int[]{1}; + } + } + return new int[0]; + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java new file mode 100644 index 00000000000..0c5e634f563 --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.java.testlibrary.dtrace; + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public interface DtraceResultsAnalyzer { + public void analyze(OutputAnalyzer oa, String logFilePath); +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java new file mode 100644 index 00000000000..bcb575c398b --- /dev/null +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.java.testlibrary.dtrace; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.OutputAnalyzer; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class DtraceRunner { + + private static final String DTRACE_DEFAULT_PATH = "/usr/sbin/dtrace"; + private static final String DTRACE_PATH_PROPERTY + = "com.oracle.test.dtrace.path"; + private static final String OUTPUT_FILE_DTRACE_OPTION = "o"; + private static final String RUN_COMMAND_DTRACE_OPTION = "c"; + private static final String RUN_SCRIPT_DTRACE_OPTION = "s"; + private static final String ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION = "Z"; + private static final String DTRACE_OPTION_PREFIX = "-"; + public static final String PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION = "w"; + public static final String DTRACE_OUT_LOG = "dtrace.out"; + + private final String dtraceExecutable; + + public DtraceRunner() { + dtraceExecutable = getDtracePath(); + } + + private List getLaunchCmd(String java, String javaOpts, + String execClass, String testArgs, String dtraceScript, + String dtraceAddOpts) { + Asserts.assertTrue(!java.matches("\\s"), "Current dtrace implementation" + + " can't handle whitespaces in application path"); + List result = new ArrayList<>(); + result.add(dtraceExecutable); + result.add(DTRACE_OPTION_PREFIX + System.getProperty("sun.arch.data.model")); + result.add(DTRACE_OPTION_PREFIX + + ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION + + ((dtraceAddOpts == null) ? "" : dtraceAddOpts) + + RUN_SCRIPT_DTRACE_OPTION); // run_script should be last one + result.add(dtraceScript); + result.add(DTRACE_OPTION_PREFIX + OUTPUT_FILE_DTRACE_OPTION); + result.add(DTRACE_OUT_LOG); + result.add(DTRACE_OPTION_PREFIX + RUN_COMMAND_DTRACE_OPTION); + result.add(java + " " + javaOpts + " " + execClass + " " + testArgs); + return result; + } + + private void backupLogFile(File file) { + if (file.exists()) { + file.renameTo(new File(file.getPath() + ".bak")); + } + } + + public void runDtrace(String java, String javaOpts, String execClass, + String testArgs, String dtraceScript, String dtraceAddOpts, + DtraceResultsAnalyzer analyzer) { + backupLogFile(new File(DTRACE_OUT_LOG)); + ProcessBuilder pbuilder = new ProcessBuilder( + getLaunchCmd(java, javaOpts, execClass, testArgs, + dtraceScript, dtraceAddOpts)); + OutputAnalyzer oa; + try { + oa = new OutputAnalyzer(pbuilder.start()); + } catch (IOException e) { + throw new Error("TESTBUG: Can't start process", e); + } + analyzer.analyze(oa, DTRACE_OUT_LOG); + } + + public static boolean dtraceAvailable() { + String path = getDtracePath(); + if (path == null) { + return false; + } + // now we'll launch dtrace to trace itself just to be sure it works + // and have all additional previleges set + ProcessBuilder pbuilder = new ProcessBuilder(path, path); + try { + OutputAnalyzer oa = new OutputAnalyzer(pbuilder.start()); + if (oa.getExitValue() != 0) { + return false; + } + } catch (IOException e) { + throw new Error("Couldn't launch dtrace", e); + } + return true; + } + + private static String getDtracePath() { + String propPath = System.getProperty(DTRACE_PATH_PROPERTY); + if (propPath != null && new File(propPath).exists()) { + return propPath; + } else if (new File(DTRACE_DEFAULT_PATH).exists()) { + return DTRACE_DEFAULT_PATH; + } + return null; + } +} From 398f9958d611bac1b2200aa5d5614c9c8dfb13df Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Tue, 30 Dec 2014 11:07:49 +0300 Subject: [PATCH 16/72] 8068272: Extend WhiteBox API with methods that check monitor state and force safepoint Reviewed-by: kvn, iignatyev --- hotspot/src/share/vm/prims/whitebox.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index afde0ae63e1..9af362b1d11 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -1123,6 +1123,16 @@ WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean attemptedNoSafepointValue == JNI_TRUE); WB_END +WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj)) + oop obj_oop = JNIHandles::resolve(obj); + return (jboolean) obj_oop->mark()->has_monitor(); +WB_END + +WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb)) + VM_ForceSafepoint force_safepoint_op; + VMThread::execute(&force_safepoint_op); +WB_END + //Some convenience methods to deal with objects from java int WhiteBox::offset_for_field(const char* field_name, oop object, Symbol* signature_symbol) { @@ -1321,6 +1331,8 @@ static JNINativeMethod methods[] = { {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, {CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls }, + {CC"isMonitorInflated", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated }, + {CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint }, }; #undef CC From add1e857d7f1a6a136c9748ae1081d088844e524 Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Tue, 30 Dec 2014 11:09:42 +0300 Subject: [PATCH 17/72] 8050486: compiler/rtm/ tests fail due to monitor deflation at safepoint synchronization Reviewed-by: kvn, iignatyev --- .../rtm/locking/TestRTMAbortRatio.java | 9 +-- .../rtm/locking/TestRTMAfterNonRTMDeopt.java | 9 +-- .../locking/TestRTMDeoptOnLowAbortRatio.java | 10 +-- .../rtm/locking/TestRTMLockingThreshold.java | 10 +-- .../locking/TestRTMTotalCountIncrRate.java | 10 +-- .../locking/TestUseRTMAfterLockInflation.java | 5 +- .../testlibrary/rtm/AbortProvoker.java | 81 ++++++++++++++----- .../compiler/testlibrary/rtm/BusyLock.java | 8 +- .../rtm/MemoryConflictProvoker.java | 10 +-- .../compiler/testlibrary/rtm/RTMTestBase.java | 3 +- 10 files changed, 99 insertions(+), 56 deletions(-) diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java index 02392f8db02..4a41d3768c5 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java @@ -127,10 +127,7 @@ public class TestRTMAbortRatio extends CommandLineOptionTest { @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void lock(boolean abort) { @@ -148,10 +145,12 @@ public class TestRTMAbortRatio extends CommandLineOptionTest { public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.lock(i >= Test.WARMUP_ITERATIONS); } } diff --git a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java index 12c659ef2d6..5269a25974b 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java @@ -157,10 +157,7 @@ public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest { @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::forceAbort" - }; + return new String[] { getMethodWithLockName() }; } public void forceAbort(int a[], boolean abort) { @@ -183,13 +180,15 @@ public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest { public static void main(String args[]) throws Throwable { Test t = new Test(); - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } int tmp[] = new int[1]; for (int i = 0; i < Test.ITERATIONS; i++ ) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); if (i == Test.RANGE_CHECK_AT) { t.forceAbort(new int[0], false); } else { diff --git a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java index 343ecc0cd83..128ec7bd403 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java @@ -130,10 +130,7 @@ public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest { @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void forceAbort(boolean abort) { @@ -151,11 +148,12 @@ public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest { public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.forceAbort( i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD); } diff --git a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java index c57065f5be0..75a94c6d989 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java @@ -143,10 +143,7 @@ public class TestRTMLockingThreshold extends CommandLineOptionTest { @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void lock(boolean abort) { @@ -164,11 +161,12 @@ public class TestRTMLockingThreshold extends CommandLineOptionTest { public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.lock(i % 2 == 1); } } diff --git a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java index 8201cb9e1a5..7a3327606fd 100644 --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java @@ -117,9 +117,7 @@ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest { @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName() - }; + return new String[] { getMethodWithLockName() }; } public void lock() { @@ -135,11 +133,13 @@ public class TestRTMTotalCountIncrRate extends CommandLineOptionTest { public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test test = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(test.monitor); } for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(test.monitor, + shouldBeInflated); test.lock(); } } diff --git a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java index ff7e98122b9..a6334703c76 100644 --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java @@ -52,7 +52,7 @@ import rtm.predicate.SupportedVM; * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before * lock inflation and the same amount of times after inflation. * As a result total locks count should be equal to - * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}. + * {@code 2 * AbortProvoker.DEFAULT_ITERATIONS}. * It is a pretty strict assertion which could fail if some retriable abort * happened: it could be {@code AbortType.RETRIABLE} or * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these @@ -101,7 +101,6 @@ public class TestUseRTMAfterLockInflation extends CommandLineOptionTest { } public static class Test { - /** * Usage: * Test <provoker type> @@ -113,10 +112,12 @@ public class TestUseRTMAfterLockInflation extends CommandLineOptionTest { AbortProvoker provoker = AbortType.lookup(Integer.valueOf(args[0])).provoker(); for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(provoker, false /*deflated*/); provoker.forceAbort(); } provoker.inflateMonitor(); for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(provoker, true /*inflated*/); provoker.forceAbort(); } } diff --git a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java index 1d129087d3d..b641ca084f8 100644 --- a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java +++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java @@ -29,8 +29,7 @@ import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import com.oracle.java.testlibrary.Asserts; -import com.oracle.java.testlibrary.Utils; -import sun.misc.Unsafe; +import sun.hotspot.WhiteBox; /** * Base class for different transactional execution abortion @@ -38,6 +37,9 @@ import sun.misc.Unsafe; */ public abstract class AbortProvoker implements CompilableTest { public static final long DEFAULT_ITERATIONS = 10000L; + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + @SuppressWarnings("unused") + private static int sharedState = 0; /** * Inflates monitor associated with object {@code monitor}. * Inflation is forced by entering the same monitor from @@ -48,36 +50,76 @@ public abstract class AbortProvoker implements CompilableTest { * @throws Exception if something went wrong. */ public static Object inflateMonitor(Object monitor) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); CyclicBarrier barrier = new CyclicBarrier(2); Runnable inflatingRunnable = () -> { - unsafe.monitorEnter(monitor); - try { - barrier.await(); - barrier.await(); - } catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException( - "Synchronization issue occurred.", e); - } finally { - unsafe.monitorExit(monitor); + synchronized (monitor) { + try { + barrier.await(); + } catch (BrokenBarrierException | InterruptedException e) { + throw new RuntimeException( + "Synchronization issue occurred.", e); + } + try { + monitor.wait(); + } catch (InterruptedException e) { + throw new AssertionError("The thread waiting on an" + + " inflated monitor was interrupted, thus test" + + " results may be incorrect.", e); + } } }; Thread t = new Thread(inflatingRunnable); + t.setDaemon(true); t.start(); // Wait until thread t enters the monitor. barrier.await(); - // At this point monitor will be owned by thread t, - // so our attempt to enter the same monitor will force - // monitor inflation. - Asserts.assertFalse(unsafe.tryMonitorEnter(monitor), - "Not supposed to enter the monitor first"); - barrier.await(); - t.join(); + synchronized (monitor) { + // At this point thread t is already waiting on the monitor. + // Modifying static field just to avoid lock's elimination. + sharedState++; + } + verifyMonitorState(monitor, true /* inflated */); return monitor; } + /** + * Verifies that {@code monitor} is a stack-lock or inflated lock depending + * on {@code shouldBeInflated} value. If {@code monitor} is inflated while + * it is expected that it should be a stack-lock, then this method attempts + * to deflate it by forcing a safepoint and then verifies the state once + * again. + * + * @param monitor monitor to be verified. + * @param shouldBeInflated flag indicating whether or not monitor is + * expected to be inflated. + * @throws RuntimeException if the {@code monitor} in a wrong state. + */ + public static void verifyMonitorState(Object monitor, + boolean shouldBeInflated) { + if (!shouldBeInflated && WHITE_BOX.isMonitorInflated(monitor)) { + WHITE_BOX.forceSafepoint(); + } + Asserts.assertEQ(WHITE_BOX.isMonitorInflated(monitor), shouldBeInflated, + "Monitor in a wrong state."); + } + /** + * Verifies that monitor used by the {@code provoker} is a stack-lock or + * inflated lock depending on {@code shouldBeInflated} value. If such + * monitor is inflated while it is expected that it should be a stack-lock, + * then this method attempts to deflate it by forcing a safepoint and then + * verifies the state once again. + * + * @param provoker AbortProvoker whose monitor's state should be verified. + * @param shouldBeInflated flag indicating whether or not monitor is + * expected to be inflated. + * @throws RuntimeException if the {@code monitor} in a wrong state. + */ + public static void verifyMonitorState(AbortProvoker provoker, + boolean shouldBeInflated) { + verifyMonitorState(provoker.monitor, shouldBeInflated); + } /** * Get instance of specified AbortProvoker, inflate associated monitor @@ -120,6 +162,7 @@ public abstract class AbortProvoker implements CompilableTest { } for (long i = 0; i < iterations; i++) { + AbortProvoker.verifyMonitorState(provoker, monitorShouldBeInflated); provoker.forceAbort(); } } diff --git a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java index 70e80f70c93..55985b61b73 100644 --- a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java +++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java @@ -77,7 +77,7 @@ public class BusyLock implements CompilableTest, Runnable { } } - public void test() { + public void syncAndTest() { try { barrier.await(); // wait until monitor is locked by a ::run method @@ -85,6 +85,10 @@ public class BusyLock implements CompilableTest, Runnable { } catch (InterruptedException | BrokenBarrierException e) { throw new RuntimeException("Synchronization error happened.", e); } + test(); + } + + public void test() { synchronized(monitor) { BusyLock.field++; } @@ -130,7 +134,7 @@ public class BusyLock implements CompilableTest, Runnable { Thread t = new Thread(busyLock); t.start(); - busyLock.test(); + busyLock.syncAndTest(); t.join(); } } diff --git a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java index 48cf799eb06..670e97511e8 100644 --- a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java +++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java @@ -69,11 +69,6 @@ class MemoryConflictProvoker extends AbortProvoker { * Accesses and modifies memory region from within the transaction. */ public void transactionalRegion() { - try { - barrier.await(); - } catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException(e); - } for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) { synchronized(monitor) { MemoryConflictProvoker.field--; @@ -86,6 +81,11 @@ class MemoryConflictProvoker extends AbortProvoker { try { Thread t = new Thread(conflictingThread); t.start(); + try { + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } transactionalRegion(); t.join(); } catch (Exception e) { diff --git a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java index c4bbcc1568d..406443a6561 100644 --- a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java @@ -240,7 +240,8 @@ public class RTMTestBase { Collections.addAll(finalVMOpts, "-Xcomp", "-server", "-XX:-TieredCompilation", "-XX:+UseRTMLocking", CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI"); if (test != null) { for (String method : test.getMethodsToCompileNames()) { From 186ca574472716590bd4cd45783182cd25f53c2a Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 22 Dec 2014 11:21:20 +0100 Subject: [PATCH 18/72] 8055530: assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty()) failed: return value must be well defined Concurrent class loading causes return phi to become top Reviewed-by: kvn --- hotspot/src/share/vm/opto/c2compiler.cpp | 7 +++++++ hotspot/src/share/vm/opto/c2compiler.hpp | 1 + hotspot/src/share/vm/opto/compile.cpp | 4 +++- hotspot/src/share/vm/opto/parse1.cpp | 14 +++++++++++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index 71e2a0bbbab..45732b2745d 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -39,6 +39,9 @@ const char* C2Compiler::retry_no_subsuming_loads() { const char* C2Compiler::retry_no_escape_analysis() { return "retry without escape analysis"; } +const char* C2Compiler::retry_class_loading_during_parsing() { + return "retry class loading during parsing"; +} bool C2Compiler::init_c2_runtime() { // Check assumptions used while running ADLC @@ -104,6 +107,10 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { // Check result and retry if appropriate. if (C.failure_reason() != NULL) { + if (C.failure_reason_is(retry_class_loading_during_parsing())) { + env->report_failure(C.failure_reason()); + continue; // retry + } if (C.failure_reason_is(retry_no_subsuming_loads())) { assert(subsume_loads, "must make progress"); subsume_loads = false; diff --git a/hotspot/src/share/vm/opto/c2compiler.hpp b/hotspot/src/share/vm/opto/c2compiler.hpp index 5d086416f4a..e457e13794f 100644 --- a/hotspot/src/share/vm/opto/c2compiler.hpp +++ b/hotspot/src/share/vm/opto/c2compiler.hpp @@ -47,6 +47,7 @@ public: // sentinel value used to trigger backtracking in compile_method(). static const char* retry_no_subsuming_loads(); static const char* retry_no_escape_analysis(); + static const char* retry_class_loading_during_parsing(); // Print compilation timers and statistics void print_timers(); diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 17ffca9e6ff..23253651dca 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -774,7 +774,9 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr } JVMState* jvms = build_start_state(start(), tf()); if ((jvms = cg->generate(jvms)) == NULL) { - record_method_not_compilable("method parse failed"); + if (!failure_reason_is(C2Compiler::retry_class_loading_during_parsing())) { + record_method_not_compilable("method parse failed"); + } return; } GraphKit kit(jvms); diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index 4508c3848c7..402ccfe5dc6 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -27,6 +27,7 @@ #include "interpreter/linkResolver.hpp" #include "oops/method.hpp" #include "opto/addnode.hpp" +#include "opto/c2compiler.hpp" #include "opto/castnode.hpp" #include "opto/idealGraphPrinter.hpp" #include "opto/locknode.hpp" @@ -986,7 +987,18 @@ void Parse::do_exits() { if (tf()->range()->cnt() > TypeFunc::Parms) { const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); Node* ret_phi = _gvn.transform( _exits.argument(0) ); - assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined"); + if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) { + // In case of concurrent class loading, the type we set for the + // ret_phi in build_exits() may have been too optimistic and the + // ret_phi may be top now. +#ifdef ASSERT + { + MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); + assert(ret_type->isa_ptr() && C->env()->system_dictionary_modification_counter_changed(), "return value must be well defined"); + } +#endif + C->record_failure(C2Compiler::retry_class_loading_during_parsing()); + } _exits.push_node(ret_type->basic_type(), ret_phi); } From 2e82794bfa61eaaac17fe932ce0a21c09e2211f4 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Tue, 16 Dec 2014 13:49:36 +0100 Subject: [PATCH 19/72] 6700100: optimize inline_native_clone() for small objects with exact klass Optimize small instance clones as loads/stores Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 31 +- hotspot/src/share/vm/ci/ciInstanceKlass.hpp | 12 + hotspot/src/share/vm/oops/fieldStreams.hpp | 2 +- hotspot/src/share/vm/opto/c2_globals.hpp | 7 + hotspot/src/share/vm/opto/callnode.cpp | 139 ++++++- hotspot/src/share/vm/opto/callnode.hpp | 35 +- hotspot/src/share/vm/opto/library_call.cpp | 43 ++- hotspot/src/share/vm/opto/macroArrayCopy.cpp | 7 +- .../arraycopy/TestArrayCopyMacro.java | 79 ++++ ....java => TestArraysCopyOfNoTypeCheck.java} | 4 +- .../TestInstanceCloneAsLoadsStores.java | 342 ++++++++++++++++++ 11 files changed, 671 insertions(+), 30 deletions(-) create mode 100644 hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java rename hotspot/test/compiler/arraycopy/{TestArrayOfNoTypeCheck.java => TestArraysCopyOfNoTypeCheck.java} (95%) create mode 100644 hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index 7a8bad33c6a..43691b907d7 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -59,7 +59,7 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : _has_nonstatic_fields = ik->has_nonstatic_fields(); _has_default_methods = ik->has_default_methods(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: - + _has_injected_fields = -1; _implementor = NULL; // we will fill these lazily Thread *thread = Thread::current(); @@ -100,6 +100,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name, _nonstatic_field_size = -1; _has_nonstatic_fields = false; _nonstatic_fields = NULL; + _has_injected_fields = -1; _loader = loader; _protection_domain = protection_domain; _is_shared = false; @@ -500,6 +501,34 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray* return fields; } +void ciInstanceKlass::compute_injected_fields_helper() { + ASSERT_IN_VM; + InstanceKlass* k = get_instanceKlass(); + + for (InternalFieldStream fs(k); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) continue; + _has_injected_fields++; + break; + } +} + +bool ciInstanceKlass::compute_injected_fields() { + assert(_has_injected_fields == -1, "shouldn't be initialized yet"); + assert(is_loaded(), "must be loaded"); + + if (super() != NULL && super()->has_injected_fields()) { + _has_injected_fields = 1; + return true; + } + + _has_injected_fields = 0; + GUARDED_VM_ENTRY({ + compute_injected_fields_helper(); + }); + + return _has_injected_fields > 0 ? true : false; +} + // ------------------------------------------------------------------ // ciInstanceKlass::find_method // diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp index ce39664b711..424b61a0a10 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp @@ -64,6 +64,7 @@ private: ciConstantPoolCache* _field_cache; // cached map index->field GrowableArray* _nonstatic_fields; + int _has_injected_fields; // any non static injected fields? lazily initialized. // The possible values of the _implementor fall into following three cases: // NULL: no implementor. @@ -71,6 +72,9 @@ private: // Itsef: more than one implementors. ciInstanceKlass* _implementor; + bool compute_injected_fields(); + void compute_injected_fields_helper(); + protected: ciInstanceKlass(KlassHandle h_k); ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); @@ -186,6 +190,14 @@ public: else return _nonstatic_fields->length(); } + + bool has_injected_fields() { + if (_has_injected_fields == -1) { + return compute_injected_fields(); + } + return _has_injected_fields > 0 ? true : false; + } + // nth nonstatic field (presented by ascending address) ciField* nonstatic_field_at(int i) { assert(_nonstatic_fields != NULL, ""); diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp index 17f1b0a8585..342c31f4fad 100644 --- a/hotspot/src/share/vm/oops/fieldStreams.hpp +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp @@ -51,7 +51,7 @@ class FieldStreamBase : public StackObj { int init_generic_signature_start_slot() { int length = _fields->length(); - int num_fields = 0; + int num_fields = _index; int skipped_generic_signature_slots = 0; FieldInfo* fi; AccessFlags flags; diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index b74dbe40bea..f7013a60e74 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -669,6 +669,13 @@ product_pd(bool, TrapBasedRangeChecks, \ "Generate code for range checks that uses a cmp and trap " \ "instruction raising SIGTRAP. Used on PPC64.") \ + \ + product(intx, ArrayCopyLoadStoreMaxElem, 8, \ + "Maximum number of arraycopy elements inlined as a sequence of" \ + "loads/stores") \ + \ + develop(bool, StressArrayCopyMacroNode, false, \ + "Perform ArrayCopy load/store replacement during IGVN only") C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 8268c97886c..f6a32496054 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -28,6 +28,7 @@ #include "opto/callGenerator.hpp" #include "opto/callnode.hpp" #include "opto/castnode.hpp" +#include "opto/convertnode.hpp" #include "opto/escape.hpp" #include "opto/locknode.hpp" #include "opto/machnode.hpp" @@ -1818,7 +1819,10 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { } ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled) - : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM), _alloc_tightly_coupled(alloc_tightly_coupled), _kind(ArrayCopy) { + : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM), + _alloc_tightly_coupled(alloc_tightly_coupled), + _kind(None), + _arguments_validated(false) { init_class_id(Class_ArrayCopy); init_flags(Flag_is_macro); C->add_macro_node(this); @@ -1870,3 +1874,136 @@ void ArrayCopyNode::dump_spec(outputStream *st) const { st->print(" (%s%s)", _kind_names[_kind], _alloc_tightly_coupled ? ", tightly coupled allocation" : ""); } #endif + +int ArrayCopyNode::get_count(PhaseGVN *phase) const { + Node* src = in(ArrayCopyNode::Src); + const Type* src_type = phase->type(src); + + assert(is_clonebasic(), "unexpected arraycopy type"); + if (src_type->isa_instptr()) { + const TypeInstPtr* inst_src = src_type->is_instptr(); + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + // ciInstanceKlass::nof_nonstatic_fields() doesn't take injected + // fields into account. They are rare anyway so easier to simply + // skip instances with injected fields. + if ((!inst_src->klass_is_exact() && (ik->is_interface() || ik->has_subklass())) || ik->has_injected_fields()) { + return -1; + } + int nb_fields = ik->nof_nonstatic_fields(); + return nb_fields; + } + return -1; +} + +Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int count) { + assert(is_clonebasic(), "unexpected arraycopy type"); + + Node* src = in(ArrayCopyNode::Src); + Node* dest = in(ArrayCopyNode::Dest); + Node* ctl = in(TypeFunc::Control); + Node* in_mem = in(TypeFunc::Memory); + + const Type* src_type = phase->type(src); + const Type* dest_type = phase->type(dest); + + assert(src->is_AddP(), "should be base + off"); + assert(dest->is_AddP(), "should be base + off"); + Node* base_src = src->in(AddPNode::Base); + Node* base_dest = dest->in(AddPNode::Base); + + MergeMemNode* mem = MergeMemNode::make(in_mem); + + const TypeInstPtr* inst_src = src_type->is_instptr(); + + if (!inst_src->klass_is_exact()) { + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy"); + phase->C->dependencies()->assert_leaf_type(ik); + } + + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields"); + + for (int i = 0; i < count; i++) { + ciField* field = ik->nonstatic_field_at(i); + int fieldidx = phase->C->alias_type(field)->index(); + const TypePtr* adr_type = phase->C->alias_type(field)->adr_type(); + Node* off = phase->MakeConX(field->offset()); + Node* next_src = phase->transform(new AddPNode(base_src,base_src,off)); + Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off)); + BasicType bt = field->layout_type(); + + const Type *type; + if (bt == T_OBJECT) { + if (!field->type()->is_loaded()) { + type = TypeInstPtr::BOTTOM; + } else { + ciType* field_klass = field->type(); + type = TypeOopPtr::make_from_klass(field_klass->as_klass()); + } + } else { + type = Type::get_const_basic_type(bt); + } + + Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered); + v = phase->transform(v); + Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered); + s = phase->transform(s); + mem->set_memory_at(fieldidx, s); + } + + if (!finish_transform(phase, can_reshape, ctl, mem)) { + return NULL; + } + + return mem; +} + +bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape, + Node* ctl, Node *mem) { + if (can_reshape) { + PhaseIterGVN* igvn = phase->is_IterGVN(); + assert(is_clonebasic(), "unexpected arraycopy type"); + Node* out_mem = proj_out(TypeFunc::Memory); + + if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() || + out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) { + assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking"); + return false; + } + + igvn->replace_node(out_mem->raw_out(0), mem); + + Node* out_ctl = proj_out(TypeFunc::Control); + igvn->replace_node(out_ctl, ctl); + } + return true; +} + + +Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { + + if (StressArrayCopyMacroNode && !can_reshape) return NULL; + + // See if it's a small array copy and we can inline it as + // loads/stores + // Here we can only do: + // - clone for which we don't need to do card marking + + if (!is_clonebasic()) { + return NULL; + } + + if (in(TypeFunc::Control)->is_top() || in(TypeFunc::Memory)->is_top()) { + return NULL; + } + + int count = get_count(phase); + + if (count < 0 || count > ArrayCopyLoadStoreMaxElem) { + return NULL; + } + + Node* mem = try_clone_instance(phase, can_reshape, count); + return mem; +} diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index 8c57610919d..ba1cd8862fd 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -1070,8 +1070,8 @@ private: // What kind of arraycopy variant is this? enum { + None, // not set yet ArrayCopy, // System.arraycopy() - ArrayCopyNoTest, // System.arraycopy(), all arguments validated CloneBasic, // A clone that can be copied by 64 bit chunks CloneOop, // An oop array clone CopyOf, // Arrays.copyOf() @@ -1095,6 +1095,8 @@ private: // LibraryCallKit::tightly_coupled_allocation() is called. bool _alloc_tightly_coupled; + bool _arguments_validated; + static const TypeFunc* arraycopy_type() { const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms); fields[Src] = TypeInstPtr::BOTTOM; @@ -1118,6 +1120,13 @@ private: ArrayCopyNode(Compile* C, bool alloc_tightly_coupled); + int get_count(PhaseGVN *phase) const; + static const TypePtr* get_address_type(PhaseGVN *phase, Node* n); + + Node* try_clone_instance(PhaseGVN *phase, bool can_reshape, int count); + bool finish_transform(PhaseGVN *phase, bool can_reshape, + Node* ctl, Node *mem); + public: enum { @@ -1143,23 +1152,23 @@ public: void connect_outputs(GraphKit* kit); - bool is_arraycopy() const { return _kind == ArrayCopy; } - bool is_arraycopy_notest() const { return _kind == ArrayCopyNoTest; } - bool is_clonebasic() const { return _kind == CloneBasic; } - bool is_cloneoop() const { return _kind == CloneOop; } - bool is_copyof() const { return _kind == CopyOf; } - bool is_copyofrange() const { return _kind == CopyOfRange; } + bool is_arraycopy() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy; } + bool is_arraycopy_validated() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy && _arguments_validated; } + bool is_clonebasic() const { assert(_kind != None, "should bet set"); return _kind == CloneBasic; } + bool is_cloneoop() const { assert(_kind != None, "should bet set"); return _kind == CloneOop; } + bool is_copyof() const { assert(_kind != None, "should bet set"); return _kind == CopyOf; } + bool is_copyofrange() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange; } - void set_arraycopy() { _kind = ArrayCopy; } - void set_arraycopy_notest() { _kind = ArrayCopyNoTest; } - void set_clonebasic() { _kind = CloneBasic; } - void set_cloneoop() { _kind = CloneOop; } - void set_copyof() { _kind = CopyOf; } - void set_copyofrange() { _kind = CopyOfRange; } + void set_arraycopy(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = ArrayCopy; _arguments_validated = validated; } + void set_clonebasic() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneBasic; } + void set_cloneoop() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneOop; } + void set_copyof() { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOf; _arguments_validated = false; } + void set_copyofrange() { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOfRange; _arguments_validated = false; } virtual int Opcode() const; virtual uint size_of() const; // Size is bigger virtual bool guaranteed_safepoint() { return false; } + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); bool is_alloc_tightly_coupled() const { return _alloc_tightly_coupled; } diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index fbe2dbdfb70..7c9da72c68e 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -4475,8 +4475,11 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b ArrayCopyNode* ac = ArrayCopyNode::make(this, false, src, NULL, dest, NULL, countx, false); ac->set_clonebasic(); Node* n = _gvn.transform(ac); - assert(n == ac, "cannot disappear"); - set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); + if (n == ac) { + set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); + } else { + set_all_memory(n); + } // If necessary, emit some card marks afterwards. (Non-arrays only.) if (card_mark) { @@ -4541,6 +4544,26 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { Node* obj = null_check_receiver(); if (stopped()) return true; + const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); + + // If we are going to clone an instance, we need its exact type to + // know the number and types of fields to convert the clone to + // loads/stores. Maybe a speculative type can help us. + if (!obj_type->klass_is_exact() && + obj_type->speculative_type() != NULL && + obj_type->speculative_type()->is_instance_klass()) { + ciInstanceKlass* spec_ik = obj_type->speculative_type()->as_instance_klass(); + if (spec_ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem && + !spec_ik->has_injected_fields()) { + ciKlass* k = obj_type->klass(); + if (!k->is_instance_klass() || + k->as_instance_klass()->is_interface() || + k->as_instance_klass()->has_subklass()) { + obj = maybe_cast_profiled_obj(obj, obj_type->speculative_type(), false); + } + } + } + Node* obj_klass = load_object_klass(obj); const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr(); const TypeOopPtr* toop = ((tklass != NULL) @@ -4743,7 +4766,7 @@ bool LibraryCallKit::inline_arraycopy() { sfpt->set_memory(map()->memory()); } - bool notest = false; + bool validated = false; const Type* src_type = _gvn.type(src); const Type* dest_type = _gvn.type(dest); @@ -4847,7 +4870,7 @@ bool LibraryCallKit::inline_arraycopy() { if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { // validate arguments: enables transformation the ArrayCopyNode - notest = true; + validated = true; RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); @@ -4922,13 +4945,15 @@ bool LibraryCallKit::inline_arraycopy() { load_object_klass(src), load_object_klass(dest), load_array_length(src), load_array_length(dest)); - if (notest) { - ac->set_arraycopy_notest(); - } + ac->set_arraycopy(validated); Node* n = _gvn.transform(ac); - assert(n == ac, "cannot disappear"); - ac->connect_outputs(this); + if (n == ac) { + ac->connect_outputs(this); + } else { + assert(validated, "shouldn't transform if all arguments not validated"); + set_all_memory(n); + } return true; } diff --git a/hotspot/src/share/vm/opto/macroArrayCopy.cpp b/hotspot/src/share/vm/opto/macroArrayCopy.cpp index 438ee0e67fa..503bd44bbb6 100644 --- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp +++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp @@ -519,7 +519,8 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode* // Test S[] against D[], not S against D, because (probably) // the secondary supertype cache is less busy for S[] than S. // This usually only matters when D is an interface. - Node* not_subtype_ctrl = ac->is_arraycopy_notest() ? top() : Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn); + Node* not_subtype_ctrl = ac->is_arraycopy_validated() ? top() : + Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn); // Plug failing path into checked_oop_disjoint_arraycopy if (not_subtype_ctrl != top()) { Node* local_ctrl = not_subtype_ctrl; @@ -1109,7 +1110,7 @@ void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) { assert(alloc != NULL, "expect alloc"); } - assert(ac->is_arraycopy() || ac->is_arraycopy_notest(), "should be an arraycopy"); + assert(ac->is_arraycopy() || ac->is_arraycopy_validated(), "should be an arraycopy"); // Compile time checks. If any of these checks cannot be verified at compile time, // we do not make a fast path for this call. Instead, we let the call remain as it @@ -1191,7 +1192,7 @@ void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) { RegionNode* slow_region = new RegionNode(1); transform_later(slow_region); - if (!ac->is_arraycopy_notest()) { + if (!ac->is_arraycopy_validated()) { // (3) operands must not be null // We currently perform our null checks with the null_check routine. // This means that the null exceptions will be reported in the caller diff --git a/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java b/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java new file mode 100644 index 00000000000..9a451af08e5 --- /dev/null +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7173584 + * @summary arraycopy as macro node + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArrayCopyMacro + * + */ + +public class TestArrayCopyMacro { + static class A { + } + + // In its own method so profiling reports both branches taken + static Object m2(Object o1, Object o2, int i) { + if (i == 4) { + return o1; + } + return o2; + } + + static Object m1(A[] src, Object dest) { + int i = 1; + + // won't be optimized out until after parsing + for (; i < 3; i *= 4) { + } + dest = m2(new A[10], dest, i); + + // dest is new array here but C2 picks the "disjoint" stub + // only if stub to call is decided after parsing + System.arraycopy(src, 0, dest, 0, 10); + return dest; + } + + public static void main(String[] args) { + A[] array_src = new A[10]; + + for (int i = 0; i < array_src.length; i++) { + array_src[i] = new A(); + } + + for (int i = 0; i < 20000; i++) { + m2(null, null, 0); + } + + for (int i = 0; i < 20000; i++) { + Object[] array_dest = (Object[])m1(array_src, null); + + for (int j = 0; j < array_src.length; j++) { + if (array_dest[j] != array_src[j]) { + throw new RuntimeException("copy failed at index " + j + " src = " + array_src[j] + " dest = " + array_dest[j]); + } + } + } + } +} diff --git a/hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java b/hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java similarity index 95% rename from hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java rename to hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java index 30e525e687e..b24bc3b780b 100644 --- a/hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java +++ b/hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java @@ -25,13 +25,13 @@ * @test * @bug 8055910 * @summary Arrays.copyOf doesn't perform subtype check - * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArrayOfNoTypeCheck + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArraysCopyOfNoTypeCheck * */ import java.util.Arrays; -public class TestArrayOfNoTypeCheck { +public class TestArraysCopyOfNoTypeCheck { static class A { } diff --git a/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java b/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java new file mode 100644 index 00000000000..d3277355472 --- /dev/null +++ b/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6700100 + * @summary small instance clone as loads/stores + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* TestInstanceCloneAsLoadsStores + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode TestInstanceCloneAsLoadsStores + * + */ + +import java.lang.reflect.*; +import java.util.*; + +public class TestInstanceCloneAsLoadsStores { + static class Base implements Cloneable { + void initialize(Class c, int i) { + for (Field f : c.getDeclaredFields()) { + setVal(f, i); + i++; + } + if (c != Base.class) { + initialize(c.getSuperclass(), i); + } + } + + Base() { + initialize(getClass(), 0); + } + + void setVal(Field f, int i) { + try { + if (f.getType() == int.class) { + f.setInt(this, i); + return; + } else if (f.getType() == short.class) { + f.setShort(this, (short)i); + return; + } else if (f.getType() == byte.class) { + f.setByte(this, (byte)i); + return; + } else if (f.getType() == long.class) { + f.setLong(this, i); + return; + } + } catch(IllegalAccessException iae) { + throw new RuntimeException("Getting fields failed"); + } + throw new RuntimeException("unexpected field type"); + } + + int getVal(Field f) { + try { + if (f.getType() == int.class) { + return f.getInt(this); + } else if (f.getType() == short.class) { + return (int)f.getShort(this); + } else if (f.getType() == byte.class) { + return (int)f.getByte(this); + } else if (f.getType() == long.class) { + return (int)f.getLong(this); + } + } catch(IllegalAccessException iae) { + throw new RuntimeException("Setting fields failed"); + } + throw new RuntimeException("unexpected field type"); + } + + boolean fields_equal(Class c, Base o) { + for (Field f : c.getDeclaredFields()) { + if (getVal(f) != o.getVal(f)) { + return false; + } + } + if (c != Base.class) { + return fields_equal(c.getSuperclass(), o); + } + return true; + } + + public boolean equals(Object obj) { + return fields_equal(getClass(), (Base)obj); + } + + String print_fields(Class c, String s) { + for (Field f : c.getDeclaredFields()) { + if (s != "") { + s += "\n"; + } + s = s + f + " = " + getVal(f); + } + if (c != Base.class) { + return print_fields(c.getSuperclass(), s); + } + return s; + } + + public String toString() { + return print_fields(getClass(), ""); + } + + int fields_sum(Class c, int s) { + for (Field f : c.getDeclaredFields()) { + s += getVal(f); + } + if (c != Base.class) { + return fields_sum(c.getSuperclass(), s); + } + return s; + } + + public int sum() { + return fields_sum(getClass(), 0); + } + + } + + static class A extends Base { + int i1; + int i2; + int i3; + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class B extends A { + int i6; + } + + static final class D extends Base { + byte i1; + short i2; + long i3; + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static final class E extends Base { + int i1; + int i2; + int i3; + int i4; + int i5; + int i6; + int i7; + int i8; + int i9; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static final class F extends Base { + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class G extends Base { + int i1; + int i2; + int i3; + + public Object myclone() throws CloneNotSupportedException { + return clone(); + } + } + + static class H extends G { + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class J extends Base { + int i1; + int i2; + int i3; + + public Object myclone() throws CloneNotSupportedException { + return clone(); + } + } + + static class K extends J { + int i4; + int i5; + } + + // Should be compiled as loads/stores + static Object m1(D src) throws CloneNotSupportedException { + return src.clone(); + } + + // Should be compiled as adds of src (dest allocation eliminated) + static int m2(D src) throws CloneNotSupportedException { + D dest = (D)src.clone(); + return dest.i1 + dest.i2 + ((int)dest.i3) + dest.i4 + dest.i5; + } + + // Should be compiled as arraycopy stub call (object too large) + static int m3(E src) throws CloneNotSupportedException { + E dest = (E)src.clone(); + return dest.i1 + dest.i2 + dest.i3 + dest.i4 + dest.i5 + + dest.i6 + dest.i7 + dest.i8 + dest.i9; + } + + // Need profiling on src's type to be able to know number of + // fields. Cannot clone as loads/stores if compile doesn't use it. + static Object m4(A src) throws CloneNotSupportedException { + return src.clone(); + } + + // Same as above but should optimize out dest allocation + static int m5(A src) throws CloneNotSupportedException { + A dest = (A)src.clone(); + return dest.i1 + dest.i2 + dest.i3 + dest.i4 + dest.i5; + } + + // Check that if we have no fields to clone we do fine + static Object m6(F src) throws CloneNotSupportedException { + return src.clone(); + } + + // With virtual call to clone: clone inlined from profling which + // gives us exact type of src so we can clone it with + // loads/stores. + static G m7(G src) throws CloneNotSupportedException { + return (G)src.myclone(); + } + + // Virtual call to clone but single target: exact type unknown, + // clone intrinsic uses profiling to determine exact type and + // clone with loads/stores. + static J m8(J src) throws CloneNotSupportedException { + return (J)src.myclone(); + } + + final HashMap tests = new HashMap<>(); + { + for (Method m : this.getClass().getDeclaredMethods()) { + if (m.getName().matches("m[0-9]+")) { + assert(Modifier.isStatic(m.getModifiers())) : m; + tests.put(m.getName(), m); + } + } + } + + boolean success = true; + + void doTest(Base src, String name) throws Exception { + Method m = tests.get(name); + + for (int i = 0; i < 20000; i++) { + boolean failure = false; + Base res = null; + int s = 0; + if (m.getReturnType().isPrimitive()) { + s = (int)m.invoke(null, src); + failure = (s != src.sum()); + } else { + res = (Base)m.invoke(null, src); + failure = !res.equals(src); + } + if (failure) { + System.out.println("Test " + name + " failed"); + System.out.println("source: "); + System.out.println(src); + System.out.println("result: "); + if (m.getReturnType().isPrimitive()) { + System.out.println(s); + } else { + System.out.println(res); + } + success = false; + break; + } + } + } + + public static void main(String[] args) throws Exception { + + TestInstanceCloneAsLoadsStores test = new TestInstanceCloneAsLoadsStores(); + + A a = new A(); + B b = new B(); + D d = new D(); + E e = new E(); + F f = new F(); + G g = new G(); + H h = new H(); + J j = new J(); + K k = new K(); + + test.doTest(d, "m1"); + test.doTest(d, "m2"); + test.doTest(e, "m3"); + test.doTest(a, "m4"); + test.doTest(a, "m5"); + test.doTest(f, "m6"); + test.doTest(g, "m7"); + test.doTest(k, "m8"); + + if (!test.success) { + throw new RuntimeException("some tests failed"); + } + + } +} From 675f6c191da3e6f423123c64b246df2ec285016b Mon Sep 17 00:00:00 2001 From: Maynard Johnson Date: Wed, 17 Dec 2014 18:20:10 +0100 Subject: [PATCH 20/72] 8049716: PPC64: Implement SA on Linux/PPC64 Reviewed-by: simonis, dsamersoff --- hotspot/agent/make/Makefile | 12 + .../agent/src/os/linux/LinuxDebuggerLocal.c | 49 +- hotspot/agent/src/os/linux/symtab.c | 37 +- .../debugger/MachineDescriptionPPC64.java | 2 +- .../debugger/linux/LinuxCDebugger.java | 12 +- .../linux/LinuxThreadContextFactory.java | 3 + .../linux/ppc64/LinuxPPC64CFrame.java | 79 +++ .../linux/ppc64/LinuxPPC64ThreadContext.java | 46 ++ .../debugger/ppc64/PPC64ThreadContext.java | 123 +++++ .../debugger/proc/ProcDebuggerLocal.java | 8 +- .../debugger/proc/ppc64/ProcPPC64Thread.java | 86 +++ .../proc/ppc64/ProcPPC64ThreadContext.java | 46 ++ .../proc/ppc64/ProcPPC64ThreadFactory.java | 44 ++ .../debugger/remote/RemoteDebuggerClient.java | 6 + .../remote/ppc64/RemotePPC64Thread.java | 53 ++ .../ppc64/RemotePPC64ThreadContext.java | 50 ++ .../ppc64/RemotePPC64ThreadFactory.java | 44 ++ .../sun/jvm/hotspot/runtime/Threads.java | 4 + .../sun/jvm/hotspot/runtime/VFrame.java | 2 +- .../LinuxPPC64JavaThreadPDAccess.java | 132 +++++ .../runtime/ppc64/PPC64CurrentFrameGuess.java | 179 ++++++ .../jvm/hotspot/runtime/ppc64/PPC64Frame.java | 513 ++++++++++++++++++ .../runtime/ppc64/PPC64JavaCallWrapper.java | 43 ++ .../runtime/ppc64/PPC64RegisterMap.java | 51 ++ hotspot/make/linux/makefiles/sa.make | 1 + hotspot/make/sa.files | 6 + hotspot/src/share/vm/runtime/vmStructs.cpp | 2 + 27 files changed, 1626 insertions(+), 7 deletions(-) create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java diff --git a/hotspot/agent/make/Makefile b/hotspot/agent/make/Makefile index 5efd67e649c..8462ef68086 100644 --- a/hotspot/agent/make/Makefile +++ b/hotspot/agent/make/Makefile @@ -58,15 +58,19 @@ sun.jvm.hotspot.debugger.cdbg.basic.x86 \ sun.jvm.hotspot.debugger.dummy \ sun.jvm.hotspot.debugger.linux \ sun.jvm.hotspot.debugger.linux.amd64 \ +sun.jvm.hotspot.debugger.linux.ppc64 \ sun.jvm.hotspot.debugger.linux.x86 \ sun.jvm.hotspot.debugger.posix \ sun.jvm.hotspot.debugger.posix.elf \ +sun.jvm.hotspot.debugger.ppc64 \ sun.jvm.hotspot.debugger.proc \ sun.jvm.hotspot.debugger.proc.amd64 \ +sun.jvm.hotspot.debugger.proc.ppc64 \ sun.jvm.hotspot.debugger.proc.sparc \ sun.jvm.hotspot.debugger.proc.x86 \ sun.jvm.hotspot.debugger.remote \ sun.jvm.hotspot.debugger.remote.amd64 \ +sun.jvm.hotspot.debugger.remote.ppc64 \ sun.jvm.hotspot.debugger.remote.sparc \ sun.jvm.hotspot.debugger.remote.x86 \ sun.jvm.hotspot.debugger.sparc \ @@ -93,9 +97,11 @@ sun.jvm.hotspot.runtime.bsd_amd64 \ sun.jvm.hotspot.runtime.bsd_x86 \ sun.jvm.hotspot.runtime.linux \ sun.jvm.hotspot.runtime.linux_amd64 \ +sun.jvm.hotspot.runtime.linux_ppc64 \ sun.jvm.hotspot.runtime.linux_sparc \ sun.jvm.hotspot.runtime.linux_x86 \ sun.jvm.hotspot.runtime.posix \ +sun.jvm.hotspot.runtime.ppc64 \ sun.jvm.hotspot.runtime.solaris_amd64 \ sun.jvm.hotspot.runtime.solaris_sparc \ sun.jvm.hotspot.runtime.solaris_x86 \ @@ -142,15 +148,19 @@ sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \ sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \ sun/jvm/hotspot/debugger/dummy/*.java \ sun/jvm/hotspot/debugger/linux/*.java \ +sun/jvm/hotspot/debugger/linux/ppc64/*.java \ sun/jvm/hotspot/debugger/linux/x86/*.java \ sun/jvm/hotspot/debugger/posix/*.java \ sun/jvm/hotspot/debugger/posix/elf/*.java \ +sun/jvm/hotspot/debugger/ppc64/*.java \ sun/jvm/hotspot/debugger/proc/*.java \ sun/jvm/hotspot/debugger/proc/amd64/*.java \ +sun/jvm/hotspot/debugger/proc/ppc64/*.java \ sun/jvm/hotspot/debugger/proc/sparc/*.java \ sun/jvm/hotspot/debugger/proc/x86/*.java \ sun/jvm/hotspot/debugger/remote/*.java \ sun/jvm/hotspot/debugger/remote/amd64/*.java \ +sun/jvm/hotspot/debugger/remote/ppc64/*.java \ sun/jvm/hotspot/debugger/remote/sparc/*.java \ sun/jvm/hotspot/debugger/remote/x86/*.java \ sun/jvm/hotspot/debugger/sparc/*.java \ @@ -174,9 +184,11 @@ sun/jvm/hotspot/runtime/bsd_amd64/*.java \ sun/jvm/hotspot/runtime/bsd_x86/*.java \ sun/jvm/hotspot/runtime/linux/*.java \ sun/jvm/hotspot/runtime/linux_amd64/*.java \ +sun/jvm/hotspot/runtime/linux_ppc64/*.java \ sun/jvm/hotspot/runtime/linux_sparc/*.java \ sun/jvm/hotspot/runtime/linux_x86/*.java \ sun/jvm/hotspot/runtime/posix/*.java \ +sun/jvm/hotspot/runtime/ppc64/*.java \ sun/jvm/hotspot/runtime/solaris_amd64/*.java \ sun/jvm/hotspot/runtime/solaris_sparc/*.java \ sun/jvm/hotspot/runtime/solaris_x86/*.java \ diff --git a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c index 5df5f1f1359..e9feeb8ebb8 100644 --- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c +++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c @@ -49,6 +49,10 @@ #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h" #endif +#ifdef ppc64 +#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h" +#endif + static jfieldID p_ps_prochandle_ID = 0; static jfieldID threadList_ID = 0; static jfieldID loadObjectList_ID = 0; @@ -341,7 +345,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo return (err == PS_OK)? array : 0; } -#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) +#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 (JNIEnv *env, jobject this_obj, jint lwp_id) { @@ -366,6 +370,10 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo #if defined(sparc) || defined(sparcv9) #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG #endif +#ifdef ppc64 +#define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG +#endif + array = (*env)->NewLongArray(env, NPRGREG); CHECK_EXCEPTION_(0); @@ -458,6 +466,45 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo regs[REG_INDEX(R_O7)] = gregs.u_regs[14]; #endif /* sparc */ +#ifdef ppc64 +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg + + regs[REG_INDEX(LR)] = gregs.link; + regs[REG_INDEX(NIP)] = gregs.nip; + regs[REG_INDEX(R0)] = gregs.gpr[0]; + regs[REG_INDEX(R1)] = gregs.gpr[1]; + regs[REG_INDEX(R2)] = gregs.gpr[2]; + regs[REG_INDEX(R3)] = gregs.gpr[3]; + regs[REG_INDEX(R4)] = gregs.gpr[4]; + regs[REG_INDEX(R5)] = gregs.gpr[5]; + regs[REG_INDEX(R6)] = gregs.gpr[6]; + regs[REG_INDEX(R7)] = gregs.gpr[7]; + regs[REG_INDEX(R8)] = gregs.gpr[8]; + regs[REG_INDEX(R9)] = gregs.gpr[9]; + regs[REG_INDEX(R10)] = gregs.gpr[10]; + regs[REG_INDEX(R11)] = gregs.gpr[11]; + regs[REG_INDEX(R12)] = gregs.gpr[12]; + regs[REG_INDEX(R13)] = gregs.gpr[13]; + regs[REG_INDEX(R14)] = gregs.gpr[14]; + regs[REG_INDEX(R15)] = gregs.gpr[15]; + regs[REG_INDEX(R16)] = gregs.gpr[16]; + regs[REG_INDEX(R17)] = gregs.gpr[17]; + regs[REG_INDEX(R18)] = gregs.gpr[18]; + regs[REG_INDEX(R19)] = gregs.gpr[19]; + regs[REG_INDEX(R20)] = gregs.gpr[20]; + regs[REG_INDEX(R21)] = gregs.gpr[21]; + regs[REG_INDEX(R22)] = gregs.gpr[22]; + regs[REG_INDEX(R23)] = gregs.gpr[23]; + regs[REG_INDEX(R24)] = gregs.gpr[24]; + regs[REG_INDEX(R25)] = gregs.gpr[25]; + regs[REG_INDEX(R26)] = gregs.gpr[26]; + regs[REG_INDEX(R27)] = gregs.gpr[27]; + regs[REG_INDEX(R28)] = gregs.gpr[28]; + regs[REG_INDEX(R29)] = gregs.gpr[29]; + regs[REG_INDEX(R30)] = gregs.gpr[30]; + regs[REG_INDEX(R31)] = gregs.gpr[31]; + +#endif (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); return array; diff --git a/hotspot/agent/src/os/linux/symtab.c b/hotspot/agent/src/os/linux/symtab.c index 077532a06f3..61c98747854 100644 --- a/hotspot/agent/src/os/linux/symtab.c +++ b/hotspot/agent/src/os/linux/symtab.c @@ -325,6 +325,12 @@ static struct symtab* build_symtab_internal(int fd, const char *filename, bool t // Reading of elf header struct elf_section *scn_cache = NULL; +#if defined(ppc64) && !defined(ABI_ELFv2) + // Only big endian ppc64 (i.e. ABI_ELFv1) has 'official procedure descriptors' in ELF files + // see: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html + struct elf_section *opd_sect = NULL; + ELF_SHDR *opd = NULL; +#endif int cnt = 0; ELF_SHDR* shbuf = NULL; ELF_SHDR* cursct = NULL; @@ -368,6 +374,14 @@ static struct symtab* build_symtab_internal(int fd, const char *filename, bool t cursct++; } +#if defined(ppc64) && !defined(ABI_ELFv2) + opd_sect = find_section_by_name(".opd", fd, &ehdr, scn_cache); + if (opd_sect != NULL && opd_sect->c_data != NULL && opd_sect->c_shdr != NULL) { + // plausibility check + opd = opd_sect->c_shdr; + } +#endif + for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { ELF_SHDR *shdr = scn_cache[cnt].c_shdr; @@ -412,6 +426,7 @@ static struct symtab* build_symtab_internal(int fd, const char *filename, bool t // copy symbols info our symtab and enter them info the hash table for (j = 0; j < n; j++, syms++) { ENTRY item, *ret; + uintptr_t sym_value; char *sym_name = symtab->strs + syms->st_name; // skip non-object and non-function symbols @@ -422,9 +437,19 @@ static struct symtab* build_symtab_internal(int fd, const char *filename, bool t if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue; symtab->symbols[j].name = sym_name; - symtab->symbols[j].offset = syms->st_value - baseaddr; symtab->symbols[j].size = syms->st_size; + sym_value = syms->st_value; +#if defined(ppc64) && !defined(ABI_ELFv2) + // see hotspot/src/share/vm/utilities/elfFuncDescTable.hpp for a detailed description + // of why we have to go this extra way via the '.opd' section on big endian ppc64 + if (opd != NULL && *sym_name != '.' && + (opd->sh_addr <= sym_value && sym_value <= opd->sh_addr + opd->sh_size)) { + sym_value = ((ELF_ADDR*)opd_sect->c_data)[(sym_value - opd->sh_addr) / sizeof(ELF_ADDR*)]; + } +#endif + + symtab->symbols[j].offset = sym_value - baseaddr; item.key = sym_name; item.data = (void *)&(symtab->symbols[j]); @@ -433,9 +458,17 @@ static struct symtab* build_symtab_internal(int fd, const char *filename, bool t } } +#if defined(ppc64) && !defined(ABI_ELFv2) + // On Linux/PPC64 the debuginfo files contain an empty function descriptor + // section (i.e. '.opd' section) which makes the resolution of symbols + // with the above algorithm impossible (we would need the have both, the + // .opd section from the library and the symbol table from the debuginfo + // file which doesn't match with the current workflow.) + goto quit; +#endif + // Look for a separate debuginfo file. if (try_debuginfo) { - // We prefer a debug symtab to an object's own symtab, so look in // the debuginfo file. We stash a copy of the old symtab in case // there is no debuginfo. diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java index 070ac8d42d6..6cc16695d99 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java @@ -34,6 +34,6 @@ public class MachineDescriptionPPC64 extends MachineDescriptionTwosComplement im } public boolean isBigEndian() { - return true; + return "big".equals(System.getProperty("sun.cpu.endian")); } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java index 91d47c60e3f..9a02dadc17b 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java @@ -26,14 +26,17 @@ package sun.jvm.hotspot.debugger.linux; import java.io.*; import java.util.*; + import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.x86.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.sparc.*; +import sun.jvm.hotspot.debugger.ppc64.*; import sun.jvm.hotspot.debugger.linux.x86.*; import sun.jvm.hotspot.debugger.linux.amd64.*; import sun.jvm.hotspot.debugger.linux.sparc.*; +import sun.jvm.hotspot.debugger.linux.ppc64.*; import sun.jvm.hotspot.utilities.*; class LinuxCDebugger implements CDebugger { @@ -96,7 +99,14 @@ class LinuxCDebugger implements CDebugger { Address pc = context.getRegisterAsAddress(SPARCThreadContext.R_O7); if (pc == null) return null; return new LinuxSPARCCFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize()); - } else { + } else if (cpu.equals("ppc64")) { + PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext(); + Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); + if (sp == null) return null; + Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC); + if (pc == null) return null; + return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize()); + } else { // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu ThreadContext context = (ThreadContext) thread.getContext(); return context.getTopFrame(dbg); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java index 44c2265d7a0..2225558000b 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java @@ -29,6 +29,7 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.linux.amd64.*; import sun.jvm.hotspot.debugger.linux.ia64.*; import sun.jvm.hotspot.debugger.linux.x86.*; +import sun.jvm.hotspot.debugger.linux.ppc64.*; import sun.jvm.hotspot.debugger.linux.sparc.*; class LinuxThreadContextFactory { @@ -42,6 +43,8 @@ class LinuxThreadContextFactory { return new LinuxIA64ThreadContext(dbg); } else if (cpu.equals("sparc")) { return new LinuxSPARCThreadContext(dbg); + } else if (cpu.equals("ppc64")) { + return new LinuxPPC64ThreadContext(dbg); } else { try { Class tcc = Class.forName("sun.jvm.hotspot.debugger.linux." + diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java new file mode 100644 index 00000000000..9c10400c2b7 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.linux.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.linux.*; +import sun.jvm.hotspot.debugger.cdbg.*; +import sun.jvm.hotspot.debugger.cdbg.basic.*; + +final public class LinuxPPC64CFrame extends BasicCFrame { + // package/class internals only + + public LinuxPPC64CFrame(LinuxDebugger dbg, Address sp, Address pc, int address_size) { + super(dbg.getCDebugger()); + this.sp = sp; + this.pc = pc; + this.dbg = dbg; + this.address_size = address_size; + } + + // override base class impl to avoid ELF parsing + public ClosestSymbol closestSymbolToPC() { + // try native lookup in debugger. + return dbg.lookup(dbg.getAddressValue(pc())); + } + + public Address pc() { + return pc; + } + + public Address localVariableBase() { + return sp; + } + + public CFrame sender(ThreadProxy thread) { + if (sp == null) { + return null; + } + + Address nextSP = sp.getAddressAt(0); + if (nextSP == null) { + return null; + } + Address nextPC = sp.getAddressAt(2 * address_size); + if (nextPC == null) { + return null; + } + return new LinuxPPC64CFrame(dbg, nextSP, nextPC, address_size); + } + + public static int PPC64_STACK_BIAS = 0; + private static int address_size; + private Address pc; + private Address sp; + private LinuxDebugger dbg; +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java new file mode 100644 index 00000000000..4a033c26aa4 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.linux.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.linux.*; + +public class LinuxPPC64ThreadContext extends PPC64ThreadContext { + private LinuxDebugger debugger; + + public LinuxPPC64ThreadContext(LinuxDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java new file mode 100644 index 00000000000..1b6dce83376 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.cdbg.*; + +/** Specifies the thread context on ppc64 platforms; only a sub-portion + * of the context is guaranteed to be present on all operating + * systems. */ + +public abstract class PPC64ThreadContext implements ThreadContext { + + // NOTE: The indices for the various registers must be maintained as + // listed across various operating systems. However, only a small + // subset of the registers' values are guaranteed to be present (and + // must be present for the SA's stack walking to work). + + public static final int R31 = 0; + public static final int R30 = 1; + public static final int R29 = 2; + public static final int R28 = 3; + public static final int R27 = 4; + public static final int R26 = 5; + public static final int R25 = 6; + public static final int R24 = 7; + public static final int R23 = 8; + public static final int R22 = 9; + public static final int R21 = 10; + public static final int R20 = 11; + public static final int R19 = 12; + public static final int R18 = 13; + public static final int R17 = 14; + public static final int R16 = 15; + public static final int R15 = 16; + public static final int R14 = 17; + public static final int R13 = 18; + public static final int R12 = 19; + public static final int R11 = 20; + public static final int R10 = 21; + public static final int R9 = 22; + public static final int R8 = 23; + public static final int R7 = 24; + public static final int R6 = 25; + public static final int R5 = 26; + public static final int R4 = 27; + public static final int R3 = 28; + public static final int R2 = 29; + public static final int R1 = 30; + public static final int R0 = 31; + public static final int NIP = 32; + public static final int LR = 33; + + public static final int NPRGREG = 34; + + private static final String[] regNames = { + "r31", "r30", "r29", "r28", "r27", "r26", "r25", "r24", + "r23", "r22", "r21", "r20", "r19", "r18", "r17", "r16", + "r15", "r14", "r13", "r12", "r11", "r10", "r9", "r8", + "r7", "r6", "r5", "r4", "r3", "r2", "r1", "r0", + "nip", "link" + }; + + public static final int PC = NIP; + public static final int SP = R1; + + private long[] data; + + public PPC64ThreadContext() { + data = new long[NPRGREG]; + } + + public int getNumRegisters() { + return NPRGREG; + } + + public String getRegisterName(int index) { + return regNames[index]; + } + + public void setRegister(int index, long value) { + data[index] = value; + } + + public long getRegister(int index) { + return data[index]; + } + + public CFrame getTopFrame(Debugger dbg) { + return null; + } + + /** This can't be implemented in this class since we would have to + * tie the implementation to, for example, the debugging system */ + public abstract void setRegisterAsAddress(int index, Address value); + + /** This can't be implemented in this class since we would have to + * tie the implementation to, for example, the debugging system */ + public abstract Address getRegisterAsAddress(int index); + +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java index 298dbfda634..67086fb9ac4 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,9 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.proc.amd64.*; import sun.jvm.hotspot.debugger.proc.sparc.*; +import sun.jvm.hotspot.debugger.proc.ppc64.*; import sun.jvm.hotspot.debugger.proc.x86.*; +import sun.jvm.hotspot.debugger.ppc64.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.sparc.*; import sun.jvm.hotspot.debugger.x86.*; @@ -86,6 +88,10 @@ public class ProcDebuggerLocal extends DebuggerBase implements ProcDebugger { threadFactory = new ProcAMD64ThreadFactory(this); pcRegIndex = AMD64ThreadContext.RIP; fpRegIndex = AMD64ThreadContext.RBP; + } else if (cpu.equals("ppc64")) { + threadFactory = new ProcPPC64ThreadFactory(this); + pcRegIndex = PPC64ThreadContext.PC; + fpRegIndex = PPC64ThreadContext.SP; } else { try { Class tfc = Class.forName("sun.jvm.hotspot.debugger.proc." + diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java new file mode 100644 index 00000000000..f51841766ff --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.proc.*; +import sun.jvm.hotspot.utilities.*; + +public class ProcPPC64Thread implements ThreadProxy { + private ProcDebugger debugger; + private int id; + + public ProcPPC64Thread(ProcDebugger debugger, Address addr) { + this.debugger = debugger; + + // FIXME: the size here should be configurable. However, making it + // so would produce a dependency on the "types" package from the + // debugger package, which is not desired. + this.id = (int) addr.getCIntegerAt(0, 4, true); + } + + public ProcPPC64Thread(ProcDebugger debugger, long id) { + this.debugger = debugger; + this.id = (int) id; + } + + public ThreadContext getContext() throws IllegalThreadStateException { + ProcPPC64ThreadContext context = new ProcPPC64ThreadContext(debugger); + long[] regs = debugger.getThreadIntegerRegisterSet(id); + if (Assert.ASSERTS_ENABLED) { + Assert.that(regs.length <= PPC64ThreadContext.NPRGREG, "size of register set is greater than " + PPC64ThreadContext.NPRGREG); + } + for (int i = 0; i < regs.length; i++) { + context.setRegister(i, regs[i]); + } + return context; + } + + public boolean canSetContext() throws DebuggerException { + return false; + } + + public void setContext(ThreadContext context) + throws IllegalThreadStateException, DebuggerException { + throw new DebuggerException("Unimplemented"); + } + + public String toString() { + return "t@" + id; + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof ProcPPC64Thread)) { + return false; + } + + return (((ProcPPC64Thread) obj).id == id); + } + + public int hashCode() { + return id; + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java new file mode 100644 index 00000000000..d65c4defcb9 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.proc.*; + +public class ProcPPC64ThreadContext extends PPC64ThreadContext { + private ProcDebugger debugger; + + public ProcPPC64ThreadContext(ProcDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java new file mode 100644 index 00000000000..115b0fd3074 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.proc.*; + +public class ProcPPC64ThreadFactory implements ProcThreadFactory { + private ProcDebugger debugger; + + public ProcPPC64ThreadFactory(ProcDebugger debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new ProcPPC64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new ProcPPC64Thread(debugger, id); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java index ffa61b548e7..b6253f6d63d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java @@ -33,6 +33,7 @@ import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.remote.sparc.*; import sun.jvm.hotspot.debugger.remote.x86.*; import sun.jvm.hotspot.debugger.remote.amd64.*; +import sun.jvm.hotspot.debugger.remote.ppc64.*; /** An implementation of Debugger which wraps a RemoteDebugger, providing remote debugging via RMI. @@ -70,6 +71,11 @@ public class RemoteDebuggerClient extends DebuggerBase implements JVMDebugger { cachePageSize = 4096; cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); unalignedAccessesOkay = true; + } else if (cpu.equals("ppc64")) { + threadFactory = new RemotePPC64ThreadFactory(this); + cachePageSize = 4096; + cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); + unalignedAccessesOkay = true; } else { try { Class tf = Class.forName("sun.jvm.hotspot.debugger.remote." + diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java new file mode 100644 index 00000000000..299ddfe4512 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.remote.*; +import sun.jvm.hotspot.utilities.*; + +public class RemotePPC64Thread extends RemoteThread { + public RemotePPC64Thread(RemoteDebuggerClient debugger, Address addr) { + super(debugger, addr); + } + + public RemotePPC64Thread(RemoteDebuggerClient debugger, long id) { + super(debugger, id); + } + + public ThreadContext getContext() throws IllegalThreadStateException { + RemotePPC64ThreadContext context = new RemotePPC64ThreadContext(debugger); + long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) : + debugger.getThreadIntegerRegisterSet(id); + if (Assert.ASSERTS_ENABLED) { + Assert.that(regs.length == PPC64ThreadContext.NPRGREG, "size of register set must match"); + } + for (int i = 0; i < regs.length; i++) { + context.setRegister(i, regs[i]); + } + return context; + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java new file mode 100644 index 00000000000..c716e249c4f --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.remote.*; + +public class RemotePPC64ThreadContext extends PPC64ThreadContext { + private RemoteDebuggerClient debugger; + + public RemotePPC64ThreadContext(RemoteDebuggerClient debugger) { + super(); + this.debugger = debugger; + } + + /** This can't be implemented in this class since we would have to + tie the implementation to, for example, the debugging system */ + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + /** This can't be implemented in this class since we would have to + tie the implementation to, for example, the debugging system */ + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java new file mode 100644 index 00000000000..a45cebecdb2 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.remote.*; + +public class RemotePPC64ThreadFactory implements RemoteThreadFactory { + private RemoteDebuggerClient debugger; + + public RemotePPC64ThreadFactory(RemoteDebuggerClient debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new RemotePPC64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new RemotePPC64Thread(debugger, id); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java index 3b6a53c5302..0714e80d9f9 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.runtime; import java.util.*; + import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.types.*; import sun.jvm.hotspot.runtime.solaris_sparc.SolarisSPARCJavaThreadPDAccess; @@ -34,6 +35,7 @@ import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess; @@ -87,6 +89,8 @@ public class Threads { access = new LinuxAMD64JavaThreadPDAccess(); } else if (cpu.equals("sparc")) { access = new LinuxSPARCJavaThreadPDAccess(); + } else if (cpu.equals("ppc64")) { + access = new LinuxPPC64JavaThreadPDAccess(); } else { try { access = (JavaThreadPDAccess) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java index ea1ec197c6e..2506d417371 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java @@ -78,7 +78,7 @@ public class VFrame { } if (f.isRuntimeFrame()) { - // This is a conversion frame. Skip this frame and try again. + // This is a conversion frame or a Stub routine. Skip this frame and try again. RegisterMap tempMap = regMap.copy(); Frame s = f.sender(tempMap); return newVFrame(s, tempMap, thread, unsafe, false); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java new file mode 100644 index 00000000000..26f132af0b6 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.linux_ppc64; + +import java.io.*; +import java.util.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.ppc64.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +public class LinuxPPC64JavaThreadPDAccess implements JavaThreadPDAccess { + private static AddressField osThreadField; + + // Field from OSThread + private static CIntegerField osThreadThreadIDField; + + // This is currently unneeded but is being kept in case we change + // the currentFrameGuess algorithm + private static final long GUESS_SCAN_RANGE = 128 * 1024; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("JavaThread"); + osThreadField = type.getAddressField("_osthread"); + + Type osThreadType = db.lookupType("OSThread"); + osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); + } + + public Address getLastJavaFP(Address addr) { + return null; + } + + public Address getLastJavaPC(Address addr) { + return null; + } + + public Address getBaseOfStackPointer(Address addr) { + return null; + } + + public Frame getLastFramePD(JavaThread thread, Address addr) { + Address fp = thread.getLastJavaFP(); + if (fp == null) { + return null; // no information + } + return new PPC64Frame(thread.getLastJavaSP(), fp); + } + + public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { + return new PPC64RegisterMap(thread, updateMap); + } + + public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + ThreadProxy t = getThreadProxy(addr); + PPC64ThreadContext context = (PPC64ThreadContext) t.getContext(); + PPC64CurrentFrameGuess guesser = new PPC64CurrentFrameGuess(context, thread); + if (!guesser.run(GUESS_SCAN_RANGE)) { + return null; + } + if (guesser.getPC() == null) { + return new PPC64Frame(guesser.getSP(), guesser.getFP()); + } else { + return new PPC64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); + } + } + + public void printThreadIDOn(Address addr, PrintStream tty) { + tty.print(getThreadProxy(addr)); + } + + public void printInfoOn(Address threadAddr, PrintStream tty) { + tty.print("Thread id: "); + printThreadIDOn(threadAddr, tty); + // tty.println("\nPostJavaState: " + getPostJavaState(threadAddr)); + } + + public Address getLastSP(Address addr) { + ThreadProxy t = getThreadProxy(addr); + PPC64ThreadContext context = (PPC64ThreadContext) t.getContext(); + return context.getRegisterAsAddress(PPC64ThreadContext.SP); + } + + public Address getLastFP(Address addr) { + return getLastSP(addr).getAddressAt(0); + } + + public ThreadProxy getThreadProxy(Address addr) { + // Addr is the address of the JavaThread. + // Fetch the OSThread (for now and for simplicity, not making a + // separate "OSThread" class in this package) + Address osThreadAddr = osThreadField.getValue(addr); + // Get the address of the _thread_id from the OSThread + Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + + JVMDebugger debugger = VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr); + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java new file mode 100644 index 00000000000..a399af0e92a --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.code.*; +import sun.jvm.hotspot.interpreter.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.ppc64.*; + +/**

Should be able to be used on all ppc64 platforms we support + (Linux/ppc64) to implement JavaThread's "currentFrameGuess()" + functionality. Input is a PPC64ThreadContext; output is SP, FP, + and PC for an PPC64Frame. Instantiation of the PPC64Frame is left + to the caller, since we may need to subclass PPC64Frame to support + signal handler frames on Unix platforms.

+ */ + +public class PPC64CurrentFrameGuess { + private PPC64ThreadContext context; + private JavaThread thread; + private Address spFound; + private Address fpFound; + private Address pcFound; + + private static final boolean DEBUG; + static { + DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null; + } + + public PPC64CurrentFrameGuess(PPC64ThreadContext context, + JavaThread thread) { + this.context = context; + this.thread = thread; + } + + /** Returns false if not able to find a frame within a reasonable range. */ + public boolean run(long regionInBytesToSearch) { + Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); + Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC); + if (sp == null) { + // Bail out if no last java frame either + if (thread.getLastJavaSP() != null) { + Address javaSP = thread.getLastJavaSP(); + Address javaFP = javaSP.getAddressAt(0); + setValues(javaSP, javaFP, null); + return true; + } + return false; + } + /* There is no frame pointer per se for the ppc64 architecture. To mirror + * the behavior of the VM frame manager, we set fp to be the caller's (i.e., "sender's") + * stack pointer, which is the back chain value contained in our sp. + */ + Address fp = sp.getAddressAt(0); + setValues(null, null, null); // Assume we're not going to find anything + + VM vm = VM.getVM(); + if (vm.isJavaPCDbg(pc)) { + if (vm.isClientCompiler()) { + // Topmost frame is a Java frame. + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing compiler frame: sp = " + + sp + ", fp = " + fp + ", pc = " + pc); + } + setValues(sp, fp, pc); + return true; + } else { + if (vm.getInterpreter().contains(pc)) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " + + sp + ", fp = " + fp + ", pc = " + pc); + } + setValues(sp, fp, pc); + return true; + } + + // This algorithm takes the current PC as a given and tries to + // find the correct corresponding SP by walking up the stack + // and repeatedly performing stackwalks (very inefficient). + for (long offset = 0; + offset < regionInBytesToSearch; + offset += vm.getAddressSize()) { + try { + Address curSP = sp.addOffsetTo(offset); + fp = curSP.getAddressAt(0); + Frame frame = new PPC64Frame(curSP, fp, pc); + RegisterMap map = thread.newRegisterMap(false); + while (frame != null) { + if (frame.isEntryFrame() && frame.entryFrameIsFirst()) { + // We were able to traverse all the way to the + // bottommost Java frame. + // This sp looks good. Keep it. + if (DEBUG) { + System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc); + } + setValues(curSP, fp, pc); + return true; + } + frame = frame.sender(map); + } + } catch (Exception e) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset); + } + // Bad SP. Try another. + } + } + + // Were not able to find a plausible SP to go with this PC. + // Bail out. + return false; + + } + } else { + // If the current program counter was not known to us as a Java + // PC, we currently assume that we are in the run-time system + // and attempt to look to thread-local storage for saved java SP. + // Note that if this is null (because we were, in fact, + // in Java code, i.e., vtable stubs or similar, and the SA + // didn't have enough insight into the target VM to understand + // that) then we are going to lose the entire stack trace for + // the thread, which is sub-optimal. FIXME. + + if (thread.getLastJavaSP() == null) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: last java sp is null"); + } + return false; // No known Java frames on stack + } + + Address javaSP = thread.getLastJavaSP(); + Address javaFP = javaSP.getAddressAt(0); + Address javaPC = thread.getLastJavaPC(); + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " + + javaSP + ", fp = " + javaFP + ", pc = " + javaPC); + } + setValues(javaSP, javaFP, javaPC); + return true; + } + } + + public Address getSP() { return spFound; } + public Address getFP() { return fpFound; } + /** May be null if getting values from thread-local storage; take + care to call the correct PPC64Frame constructor to recover this if + necessary */ + public Address getPC() { return pcFound; } + + private void setValues(Address sp, Address fp, Address pc) { + spFound = sp; + fpFound = fp; + pcFound = pc; + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java new file mode 100644 index 00000000000..c996b6dc0de --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import java.util.*; +import sun.jvm.hotspot.code.*; +import sun.jvm.hotspot.compiler.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.oops.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +/** Specialization of and implementation of abstract methods of the + Frame class for the ppc64 family of CPUs. */ + +public class PPC64Frame extends Frame { + private static final boolean DEBUG; + static { + DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null; + } + + // All frames + private static final int SENDER_SP_OFFSET = 0; + + // Interpreter frames + private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only + private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4; + private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; + private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1; + private static final int INTERPRETER_FRAME_ESP_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1; + private static final int INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_ESP_OFFSET - 1; + private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1; + private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; + private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1; + private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; + private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway + private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; + private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; + + // Entry frames + private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET; + + // Native frames + private static int NATIVE_FRAME_INITIAL_PARAM_OFFSET; + + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + int abi_minframe_size = db.lookupIntConstant("frame::abi_minframe_size").intValue(); + int entry_frame_locals_size = db.lookupIntConstant("frame::entry_frame_locals_size").intValue(); + int wordLength = (int) VM.getVM().getAddressSize(); + NATIVE_FRAME_INITIAL_PARAM_OFFSET = -abi_minframe_size/wordLength; + ENTRY_FRAME_CALL_WRAPPER_OFFSET = -entry_frame_locals_size/wordLength; + } + + + // an additional field beyond sp and pc: + Address raw_fp; // frame pointer + private Address raw_unextendedSP; + + private PPC64Frame() { + } + + private void adjustForDeopt() { + if ( pc != null) { + // Look for a deopt pc and if it is deopted convert to original pc + CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc); + if (cb != null && cb.isJavaMethod()) { + NMethod nm = (NMethod) cb; + if (pc.equals(nm.deoptHandlerBegin())) { + if (Assert.ASSERTS_ENABLED) { + Assert.that(this.getUnextendedSP() != null, "null SP in Java frame"); + } + // adjust pc if frame is deoptimized. + pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset()); + deoptimized = true; + } + } + } + } + + public PPC64Frame(Address raw_sp, Address raw_fp, Address pc) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_sp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + if (pc == null) { + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + } else { + this.pc = pc; + } + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, fp, pc): " + this); + dumpStack(); + } + } + + public PPC64Frame(Address raw_sp, Address raw_fp) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_sp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, fp): " + this); + dumpStack(); + } + } + + public PPC64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_unextendedSp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + if (pc == null) { + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + } else { + this.pc = pc; + } + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, unextendedSP, fp, pc): " + this); + dumpStack(); + } + + } + + public Object clone() { + PPC64Frame frame = new PPC64Frame(); + frame.raw_sp = raw_sp; + frame.raw_unextendedSP = raw_unextendedSP; + frame.raw_fp = raw_fp; + frame.pc = pc; + frame.deoptimized = deoptimized; + return frame; + } + + public boolean equals(Object arg) { + if (arg == null) { + return false; + } + + if (!(arg instanceof PPC64Frame)) { + return false; + } + + PPC64Frame other = (PPC64Frame) arg; + + return (AddressOps.equal(getSP(), other.getSP()) && + AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) && + AddressOps.equal(getFP(), other.getFP()) && + AddressOps.equal(getPC(), other.getPC())); + } + + public int hashCode() { + if (raw_sp == null) { + return 0; + } + + return raw_sp.hashCode(); + } + + public String toString() { + return "sp: " + (getSP() == null ? "null" : getSP().toString()) + + ", unextendedSP: " + (getUnextendedSP() == null ? "null" : getUnextendedSP().toString()) + + ", fp: " + (getFP() == null ? "null" : getFP().toString()) + + ", pc: " + (pc == null ? "null" : pc.toString()); + } + + // accessors for the instance variables + public Address getFP() { return raw_fp; } + public Address getSP() { return raw_sp; } + public Address getID() { return raw_sp; } + + // FIXME: not implemented yet (should be done for Solaris/PPC64) + public boolean isSignalHandlerFrameDbg() { return false; } + public int getSignalNumberDbg() { return 0; } + public String getSignalNameDbg() { return null; } + + public boolean isInterpretedFrameValid() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isInterpretedFrame(), "Not an interpreted frame"); + } + + // These are reasonable sanity checks + if (getFP() == null || getFP().andWithMask(0x3) != null) { + return false; + } + + if (getSP() == null || getSP().andWithMask(0x3) != null) { + return false; + } + + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (getFP().lessThanOrEqual(getSP())) { + // this attempts to deal with unsigned comparison above + return false; + } + + if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) { + // stack frames shouldn't be large. + return false; + } + + return true; + } + + // FIXME: not applicable in current system + // void patch_pc(Thread* thread, address pc); + + public Frame sender(RegisterMap regMap, CodeBlob cb) { + PPC64RegisterMap map = (PPC64RegisterMap) regMap; + + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + + // Default is we done have to follow them. The sender_for_xxx will + // update it accordingly + map.setIncludeArgumentOops(false); + + if (isEntryFrame()) return senderForEntryFrame(map); + if (isInterpretedFrame()) return senderForInterpreterFrame(map); + + if(cb == null) { + cb = VM.getVM().getCodeCache().findBlob(getPC()); + } else { + if (Assert.ASSERTS_ENABLED) { + Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same"); + } + } + + if (cb != null) { + return senderForCompiledFrame(map, cb); + } + + // Must be native-compiled frame, i.e. the marshaling code for native + // methods that exists in the core system. + return new PPC64Frame(getSenderSP(), getLink(), getSenderPC()); + } + + private Frame senderForEntryFrame(PPC64RegisterMap map) { + if (DEBUG) { + System.out.println("senderForEntryFrame"); + } + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + // Java frame called from C; skip all C frames and return top C + // frame of that chunk as the sender + PPC64JavaCallWrapper jcw = (PPC64JavaCallWrapper) getEntryFrameCallWrapper(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero"); + Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack"); + } + PPC64Frame fr; + if (jcw.getLastJavaPC() != null) { + fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC()); + } else { + fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP()); + } + map.clear(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(map.getIncludeArgumentOops(), "should be set by clear"); + } + return fr; + } + + //------------------------------------------------------------------------------ + // frame::adjust_unextended_sp + private void adjustUnextendedSP() { + raw_unextendedSP = getFP(); + } + private Frame senderForInterpreterFrame(PPC64RegisterMap map) { + if (DEBUG) { + System.out.println("senderForInterpreterFrame"); + } + Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); + Address sp = getSenderSP(); + + return new PPC64Frame(sp, unextendedSP, getLink(), getSenderPC()); + } + + + private Frame senderForCompiledFrame(PPC64RegisterMap map, CodeBlob cb) { + if (DEBUG) { + System.out.println("senderForCompiledFrame"); + } + + // + // NOTE: some of this code is (unfortunately) duplicated in PPC64CurrentFrameGuess + // + + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + + // frame owned by optimizing compiler + if (Assert.ASSERTS_ENABLED) { + Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size"); + } + Address senderSP = getSenderSP(); + + Address senderPC = getSenderPC(); + + if (map.getUpdateMap()) { + // Tell GC to use argument oopmaps for some runtime stubs that need it. + // For C1, the runtime stub might not have oop maps, so set this flag + // outside of update_register_map. + map.setIncludeArgumentOops(cb.callerMustGCArguments()); + + if (cb.getOopMaps() != null) { + OopMapSet.updateRegisterMap(this, cb, map, true); + } + } + + return new PPC64Frame(senderSP, getLink(), senderPC); + } + + protected boolean hasSenderPD() { + // FIXME + return true; + } + + public long frameSize() { + return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize()); + } + + public Address getLink() { + return getSenderSP().getAddressAt(0); + } + + public Address getUnextendedSP() { return raw_unextendedSP; } + + // Return address: + public Address getSenderPC() { return getSenderSP().getAddressAt(2 * VM.getVM().getAddressSize()); } + + // return address of param, zero origin index. + // MPJ note: Appears to be unused. + public Address getNativeParamAddr(int idx) { + return null; + // return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx); + } + + public Address getSenderSP() { return getFP(); } + public Address addressOfInterpreterFrameLocals() { + return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET); + } + + private Address addressOfInterpreterFrameBCX() { + return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET); + } + + public int getInterpreterFrameBCI() { + // FIXME: this is not atomic with respect to GC and is unsuitable + // for use in a non-debugging, or reflective, system. Need to + // figure out how to express this. + Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0); + Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0); + Method method = (Method)Metadata.instantiateWrapperFor(methodHandle); + return bcpToBci(bcp, method); + } + + public Address addressOfInterpreterFrameMDX() { + return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET); + } + + // FIXME + //inline int frame::interpreter_frame_monitor_size() { + // return BasicObjectLock::size(); + //} + + // expression stack + // (the max_stack arguments are used by the GC; see class FrameClosure) + + public Address addressOfInterpreterFrameExpressionStack() { + Address monitorEnd = interpreterFrameMonitorEnd().address(); + return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize()); + } + + public int getInterpreterFrameExpressionStackDirection() { return -1; } + + // top of expression stack + public Address addressOfInterpreterFrameTOS() { + return getSP(); + } + + /** Expression stack from top down */ + public Address addressOfInterpreterFrameTOSAt(int slot) { + return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize()); + } + + public Address getInterpreterFrameSenderSP() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isInterpretedFrame(), "interpreted frame expected"); + } + return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); + } + + // Monitors + public BasicObjectLock interpreterFrameMonitorBegin() { + return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET)); + } + + public BasicObjectLock interpreterFrameMonitorEnd() { + Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0); + if (Assert.ASSERTS_ENABLED) { + // make sure the pointer points inside the frame + Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer"); + Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer"); + } + return new BasicObjectLock(result); + } + + public int interpreterFrameMonitorSize() { + return BasicObjectLock.size(); + } + + // Method + public Address addressOfInterpreterFrameMethod() { + return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET); + } + + // Constant pool cache + public Address addressOfInterpreterFrameCPCache() { + return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET); + } + + // Entry frames + public JavaCallWrapper getEntryFrameCallWrapper() { + return new PPC64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0)); + } + + protected Address addressOfSavedOopResult() { + // offset is 2 for compiler2 and 3 for compiler1 + return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) * + VM.getVM().getAddressSize()); + } + + protected Address addressOfSavedReceiver() { + return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize()); + } + + private void dumpStack() { + if (getFP() != null) { + for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); + AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize())); + addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { + System.out.println(addr + ": " + addr.getAddressAt(0)); + } + } else { + for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); + AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize())); + addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { + System.out.println(addr + ": " + addr.getAddressAt(0)); + } + } + } +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java new file mode 100644 index 00000000000..427d39b2eed --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import java.util.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.runtime.*; + +public class PPC64JavaCallWrapper extends JavaCallWrapper { + + public PPC64JavaCallWrapper(Address addr) { + super(addr); + } + + public Address getLastJavaFP() { + return null; + } + +} diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java new file mode 100644 index 00000000000..ca06fc413e2 --- /dev/null +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 20014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; + +public class PPC64RegisterMap extends RegisterMap { + + /** This is the only public constructor */ + public PPC64RegisterMap(JavaThread thread, boolean updateMap) { + super(thread, updateMap); + } + + protected PPC64RegisterMap(RegisterMap map) { + super(map); + } + + public Object clone() { + PPC64RegisterMap retval = new PPC64RegisterMap(this); + return retval; + } + + // no PD state to clear or copy: + protected void clearPD() {} + protected void initializePD() {} + protected void initializeFromPD(RegisterMap map) {} + protected Address getLocationPD(VMReg reg) { return null; } +} diff --git a/hotspot/make/linux/makefiles/sa.make b/hotspot/make/linux/makefiles/sa.make index 178c5555425..4c41e63df55 100644 --- a/hotspot/make/linux/makefiles/sa.make +++ b/hotspot/make/linux/makefiles/sa.make @@ -109,6 +109,7 @@ $(GENERATED)/sa-jdi.jar:: $(AGENT_FILES) $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext + $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ppc64.PPC64ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler clean: diff --git a/hotspot/make/sa.files b/hotspot/make/sa.files index faad4dd109f..fa807c36dfc 100644 --- a/hotspot/make/sa.files +++ b/hotspot/make/sa.files @@ -51,16 +51,20 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/cdbg/basic/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/elf/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \ @@ -90,12 +94,14 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/posix/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/soql/*.java \ diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 327e0f0009c..58b1a97a18e 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2559,6 +2559,8 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; /**********************/ \ /* frame */ \ /**********************/ \ + NOT_ZERO(PPC64_ONLY(declare_constant(frame::abi_minframe_size))) \ + NOT_ZERO(PPC64_ONLY(declare_constant(frame::entry_frame_locals_size))) \ \ NOT_ZERO(X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))) \ declare_constant(frame::pc_return_offset) \ From b0ad035af4d9360bfa07662f58419b3a2e41e04e Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 17 Dec 2014 23:34:52 -0500 Subject: [PATCH 21/72] 8059510: Compact symbol table layout inside shared archive Use separate compact table for shared symbols. Reviewed-by: iklam, gziemski, shade, sla, jrose --- .../share/vm/classfile/compactHashtable.cpp | 417 ++++++++++++++++++ .../share/vm/classfile/compactHashtable.hpp | 405 +++++++++++++++++ .../src/share/vm/classfile/stringTable.cpp | 58 ++- .../src/share/vm/classfile/stringTable.hpp | 2 +- .../src/share/vm/classfile/symbolTable.cpp | 112 ++++- .../src/share/vm/classfile/symbolTable.hpp | 36 +- .../src/share/vm/memory/metaspaceShared.cpp | 64 ++- .../src/share/vm/memory/metaspaceShared.hpp | 14 + hotspot/src/share/vm/memory/universe.cpp | 4 +- hotspot/src/share/vm/runtime/globals.hpp | 3 + .../src/share/vm/runtime/vm_operations.hpp | 1 + .../share/vm/services/diagnosticCommand.cpp | 3 + .../DumpSymbolAndStringTable.java | 56 +++ .../SharedSymbolTableBucketSize.java | 67 +++ 14 files changed, 1172 insertions(+), 70 deletions(-) create mode 100644 hotspot/src/share/vm/classfile/compactHashtable.cpp create mode 100644 hotspot/src/share/vm/classfile/compactHashtable.hpp create mode 100644 hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java create mode 100644 hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java diff --git a/hotspot/src/share/vm/classfile/compactHashtable.cpp b/hotspot/src/share/vm/classfile/compactHashtable.cpp new file mode 100644 index 00000000000..157b1681425 --- /dev/null +++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "classfile/javaClasses.hpp" +#include "memory/metaspaceShared.hpp" +#include "utilities/numberSeq.hpp" +#include + +///////////////////////////////////////////////////// +// +// The compact hash table writer implementations +// +CompactHashtableWriter::CompactHashtableWriter(const char* table_name, + int num_entries, + CompactHashtableStats* stats) { + assert(DumpSharedSpaces, "dump-time only"); + _table_name = table_name; + _num_entries = num_entries; + _num_buckets = number_of_buckets(_num_entries); + _buckets = NEW_C_HEAP_ARRAY(Entry*, _num_buckets, mtSymbol); + memset(_buckets, 0, sizeof(Entry*) * _num_buckets); + + /* bucket sizes table */ + _bucket_sizes = NEW_C_HEAP_ARRAY(juint, _num_buckets, mtSymbol); + memset(_bucket_sizes, 0, sizeof(juint) * _num_buckets); + + stats->hashentry_count = _num_entries; + // Compact buckets' entries will have only the 4-byte offset, but + // we don't know how many there will be at this point. So use a + // conservative estimate here. The size is adjusted later when we + // write out the buckets. + stats->hashentry_bytes = _num_entries * 8; + stats->bucket_count = _num_buckets; + stats->bucket_bytes = (_num_buckets + 1) * (sizeof(juint)); + _stats = stats; + + // See compactHashtable.hpp for table layout + _required_bytes = sizeof(juint) * 2; // _base_address, written as 2 juints + _required_bytes+= sizeof(juint) + // num_entries + sizeof(juint) + // num_buckets + stats->hashentry_bytes + + stats->bucket_bytes; +} + +CompactHashtableWriter::~CompactHashtableWriter() { + for (int index = 0; index < _num_buckets; index++) { + Entry* next = NULL; + for (Entry* tent = _buckets[index]; tent; tent = next) { + next = tent->next(); + delete tent; + } + } + + FREE_C_HEAP_ARRAY(juint, _bucket_sizes); + FREE_C_HEAP_ARRAY(Entry*, _buckets); +} + +// Calculate the number of buckets in the temporary hash table +int CompactHashtableWriter::number_of_buckets(int num_entries) { + const int buksize = (int)SharedSymbolTableBucketSize; + int num_buckets = (num_entries + buksize - 1) / buksize; + num_buckets = (num_buckets + 1) & (~0x01); + + return num_buckets; +} + +// Add a symbol entry to the temporary hash table +void CompactHashtableWriter::add(unsigned int hash, Entry* entry) { + int index = hash % _num_buckets; + entry->set_next(_buckets[index]); + _buckets[index] = entry; + _bucket_sizes[index] ++; +} + +// Write the compact table's bucket infos +juint* CompactHashtableWriter::dump_table(juint* p, juint** first_bucket, + NumberSeq* summary) { + int index; + juint* compact_table = p; + // Find the start of the buckets, skip the compact_bucket_infos table + // and the table end offset. + juint offset = _num_buckets + 1; + *first_bucket = compact_table + offset; + + for (index = 0; index < _num_buckets; index++) { + int bucket_size = _bucket_sizes[index]; + if (bucket_size == 1) { + // bucket with one entry is compacted and only has the symbol offset + compact_table[index] = BUCKET_INFO(offset, COMPACT_BUCKET_TYPE); + offset += bucket_size; // each entry contains symbol offset only + } else { + // regular bucket, each entry is a symbol (hash, offset) pair + compact_table[index] = BUCKET_INFO(offset, REGULAR_BUCKET_TYPE); + offset += bucket_size * 2; // each hash entry is 2 juints + } + if (offset & ~BUCKET_OFFSET_MASK) { + vm_exit_during_initialization("CompactHashtableWriter::dump_table: Overflow! " + "Too many symbols."); + } + summary->add(bucket_size); + } + // Mark the end of the table + compact_table[_num_buckets] = BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE); + + return compact_table; +} + +// Write the compact table's entries +juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p, + NumberSeq* summary) { + uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); + uintx max_delta = uintx(MetaspaceShared::shared_rs()->size()); + assert(max_delta <= 0x7fffffff, "range check"); + int num_compact_buckets = 0; + + assert(p != NULL, "sanity"); + for (int index = 0; index < _num_buckets; index++) { + juint count = 0; + int bucket_size = _bucket_sizes[index]; + int bucket_type = BUCKET_TYPE(compact_table[index]); + + if (bucket_size == 1) { + assert(bucket_type == COMPACT_BUCKET_TYPE, "Bad bucket type"); + num_compact_buckets ++; + } + for (Entry* tent = _buckets[index]; tent; + tent = tent->next()) { + if (bucket_type == REGULAR_BUCKET_TYPE) { + *p++ = juint(tent->hash()); // write symbol hash + } + uintx deltax = uintx(tent->value()) - base_address; + assert(deltax < max_delta, "range check"); + juint delta = juint(deltax); + *p++ = delta; // write symbol offset + count ++; + } + assert(count == _bucket_sizes[index], "sanity"); + } + + // Adjust the hashentry_bytes in CompactHashtableStats. Each compact + // bucket saves 4-byte. + _stats->hashentry_bytes -= num_compact_buckets * 4; + + return p; +} + +// Write the compact table +void CompactHashtableWriter::dump(char** top, char* end) { + NumberSeq summary; + char* old_top = *top; + juint* p = (juint*)(*top); + + uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); + + *p++ = high(base_address); + *p++ = low (base_address); // base address + *p++ = _num_entries; // number of entries in the table + *p++ = _num_buckets; // number of buckets in the table + + juint* first_bucket = NULL; + juint* compact_table = dump_table(p, &first_bucket, &summary); + juint* bucket_end = dump_buckets(compact_table, first_bucket, &summary); + + assert(bucket_end <= (juint*)end, "cannot write past end"); + *top = (char*)bucket_end; + + if (PrintSharedSpaces) { + double avg_cost = 0.0; + if (_num_entries > 0) { + avg_cost = double(_required_bytes)/double(_num_entries); + } + tty->print_cr("Shared %s table stats -------- base: " PTR_FORMAT, _table_name, (intptr_t)base_address); + tty->print_cr("Number of entries : %9d", _num_entries); + tty->print_cr("Total bytes used : %9d", (int)((*top) - old_top)); + tty->print_cr("Average bytes per entry : %9.3f", avg_cost); + tty->print_cr("Average bucket size : %9.3f", summary.avg()); + tty->print_cr("Variance of bucket size : %9.3f", summary.variance()); + tty->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); + tty->print_cr("Maximum bucket size : %9d", (int)summary.maximum()); + } +} + +///////////////////////////////////////////////////////////// +// +// The CompactHashtable implementation +// +template const char* CompactHashtable::init(const char* buffer) { + assert(!DumpSharedSpaces, "run-time only"); + juint*p = (juint*)buffer; + juint upper = *p++; + juint lower = *p++; + _base_address = uintx(jlong_from(upper, lower)); + _entry_count = *p++; + _bucket_count = *p++; + _buckets = p; + _table_end_offset = BUCKET_OFFSET(p[_bucket_count]); // located at the end of the bucket_info table + + juint *end = _buckets + _table_end_offset; + return (const char*)end; +} + +// Explicitly instantiate these types +template class CompactHashtable; + +#ifndef O_BINARY // if defined (Win32) use binary files. +#define O_BINARY 0 // otherwise do nothing. +#endif + +//////////////////////////////////////////////////////// +// +// HashtableTextDump +// +HashtableTextDump::HashtableTextDump(const char* filename) : _fd(-1) { + struct stat st; + if (os::stat(filename, &st) != 0) { + quit("Unable to get hashtable dump file size", filename); + } + _size = st.st_size; + _fd = open(filename, O_RDONLY | O_BINARY, 0); + if (_fd < 0) { + quit("Unable to open hashtable dump file", filename); + } + _base = os::map_memory(_fd, filename, 0, NULL, _size, true, false); + if (_base == NULL) { + quit("Unable to map hashtable dump file", filename); + } + _p = _base; + _end = _base + st.st_size; + _filename = filename; +} + +HashtableTextDump::~HashtableTextDump() { + os::unmap_memory((char*)_base, _size); + if (_fd >= 0) { + close(_fd); + } +} + +void HashtableTextDump::quit(const char* err, const char* msg) { + vm_exit_during_initialization(err, msg); +} + +void HashtableTextDump::corrupted(const char *p) { + char info[60]; + sprintf(info, "corrupted at pos %d", (int)(p - _base)); + quit(info, _filename); +} + +bool HashtableTextDump::skip_newline() { + if (_p[0] == '\r' && _p[1] == '\n') { + _p += 2; + } else if (_p[0] == '\n') { + _p += 1; + } else { + corrupted(_p); + } + return true; +} + +int HashtableTextDump::skip(char must_be_char) { + corrupted_if(remain() < 1); + corrupted_if(*_p++ != must_be_char); + return 0; +} + +void HashtableTextDump::skip_past(char c) { + for (;;) { + corrupted_if(remain() < 1); + if (*_p++ == c) { + return; + } + } +} + +void HashtableTextDump::check_version(const char* ver) { + int len = (int)strlen(ver); + corrupted_if(remain() < len); + if (strncmp(_p, ver, len) != 0) { + quit("wrong version of hashtable dump file", _filename); + } + _p += len; + skip_newline(); +} + + +int HashtableTextDump::scan_prefix() { + // Expect /[0-9]+: / + int utf8_length = get_num(':'); + if (*_p != ' ') { + corrupted(_p); + } + _p++; + return utf8_length; +} + +int HashtableTextDump::scan_prefix2() { + // Expect /[0-9]+ (-|)[0-9]+: / + int utf8_length = get_num(' '); + if (*_p == '-') { + _p++; + } + (void)get_num(':'); + if (*_p != ' ') { + corrupted(_p); + } + _p++; + return utf8_length; +} + +jchar HashtableTextDump::unescape(const char* from, const char* end, int count) { + jchar value = 0; + + corrupted_if(from + count > end); + + for (int i=0; i 0 && from < end; n--) { + if (*from != '\\') { + *to++ = *from++; + } else { + corrupted_if(from + 2 > end); + char c = from[1]; + from += 2; + switch (c) { + case 'x': + { + jchar value = unescape(from, end, 2); + from += 2; + assert(value <= 0xff, "sanity"); + *to++ = (char)(value & 0xff); + } + break; + case 't': *to++ = '\t'; break; + case 'n': *to++ = '\n'; break; + case 'r': *to++ = '\r'; break; + case '\\': *to++ = '\\'; break; + default: + ShouldNotReachHere(); + } + } + } + corrupted_if(n > 0); // expected more chars but file has ended + _p = from; + skip_newline(); +} + +// NOTE: the content is NOT the same as +// UTF8::as_quoted_ascii(const char* utf8_str, int utf8_length, char* buf, int buflen). +// We want to escape \r\n\t so that output [1] is more readable; [2] can be more easily +// parsed by scripts; [3] quickly processed by HashtableTextDump::get_utf8() +void HashtableTextDump::put_utf8(outputStream* st, const char* utf8_string, int utf8_length) { + const char *c = utf8_string; + const char *end = c + utf8_length; + for (; c < end; c++) { + switch (*c) { + case '\t': st->print("\\t"); break; + case '\r': st->print("\\r"); break; + case '\n': st->print("\\n"); break; + case '\\': st->print("\\\\"); break; + default: + if (isprint(*c)) { + st->print("%c", *c); + } else { + st->print("\\x%02x", ((unsigned int)*c) & 0xff); + } + } + } +} diff --git a/hotspot/src/share/vm/classfile/compactHashtable.hpp b/hotspot/src/share/vm/classfile/compactHashtable.hpp new file mode 100644 index 00000000000..ac01fa7114b --- /dev/null +++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp @@ -0,0 +1,405 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP +#define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP + +#include "classfile/stringTable.hpp" +#include "classfile/symbolTable.hpp" +#include "memory/allocation.inline.hpp" +#include "oops/symbol.hpp" +#include "services/diagnosticCommand.hpp" +#include "utilities/hashtable.hpp" + +class NumberSeq; + +// Stats for symbol tables in the CDS archive +class CompactHashtableStats VALUE_OBJ_CLASS_SPEC { +public: + int hashentry_count; + int hashentry_bytes; + int bucket_count; + int bucket_bytes; +}; + +///////////////////////////////////////////////////////////////////////// +// +// The compact hash table writer. Used at dump time for writing out +// the compact table to the shared archive. +// +// At dump time, the CompactHashtableWriter obtains all entries from the +// symbol table and adds them to a new temporary hash table. The hash +// table size (number of buckets) is calculated using +// '(num_entries + bucket_size - 1) / bucket_size'. The default bucket +// size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option. +// 4 is chosen because it produces smaller sized bucket on average for +// faster lookup. It also has relatively small number of empty buckets and +// good distribution of the entries. +// +// We use a simple hash function (symbol_hash % num_bucket) for the table. +// The new table is compacted when written out. Please see comments +// above the CompactHashtable class for the table layout detail. The bucket +// offsets are written to the archive as part of the compact table. The +// bucket offset is encoded in the low 30-bit (0-29) and the bucket type +// (regular or compact) are encoded in bit[31, 30]. For buckets with more +// than one entry, both symbol hash and symbol offset are written to the +// table. For buckets with only one entry, only the symbol offset is written +// to the table and the buckets are tagged as compact in their type bits. +// Buckets without entry are skipped from the table. Their offsets are +// still written out for faster lookup. +// +class CompactHashtableWriter: public StackObj { +public: + class Entry: public CHeapObj { + Entry* _next; + unsigned int _hash; + void* _literal; + + public: + Entry(unsigned int hash, Symbol *symbol) : _next(NULL), _hash(hash), _literal(symbol) {} + + void *value() { + return _literal; + } + Symbol *symbol() { + return (Symbol*)_literal; + } + unsigned int hash() { + return _hash; + } + Entry *next() {return _next;} + void set_next(Entry *p) {_next = p;} + }; // class CompactHashtableWriter::Entry + +private: + static int number_of_buckets(int num_entries); + + const char* _table_name; + int _num_entries; + int _num_buckets; + juint* _bucket_sizes; + Entry** _buckets; + int _required_bytes; + CompactHashtableStats* _stats; + +public: + // This is called at dump-time only + CompactHashtableWriter(const char* table_name, int num_entries, CompactHashtableStats* stats); + ~CompactHashtableWriter(); + + int get_required_bytes() { + return _required_bytes; + } + + void add(unsigned int hash, Symbol* symbol) { + add(hash, new Entry(hash, symbol)); + } + +private: + void add(unsigned int hash, Entry* entry); + juint* dump_table(juint* p, juint** first_bucket, NumberSeq* summary); + juint* dump_buckets(juint* table, juint* p, NumberSeq* summary); + +public: + void dump(char** top, char* end); +}; + +#define REGULAR_BUCKET_TYPE 0 +#define COMPACT_BUCKET_TYPE 1 +#define TABLEEND_BUCKET_TYPE 3 +#define BUCKET_OFFSET_MASK 0x3FFFFFFF +#define BUCKET_OFFSET(info) ((info) & BUCKET_OFFSET_MASK) +#define BUCKET_TYPE_SHIFT 30 +#define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT) +#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK)) + +///////////////////////////////////////////////////////////////////////////// +// +// CompactHashtable is used to stored the CDS archive's symbol table. Used +// at runtime only to access the compact table from the archive. +// +// Because these tables are read-only (no entries can be added/deleted) at run-time +// and tend to have large number of entries, we try to minimize the footprint +// cost per entry. +// +// Layout of compact symbol table in the shared archive: +// +// uintx base_address; +// juint num_symbols; +// juint num_buckets; +// juint bucket_infos[num_buckets+1]; // bit[31,30]: type; bit[29-0]: offset +// juint table[] +// +// ----------------------------------- +// | base_address | num_symbols | +// |---------------------------------| +// | num_buckets | bucket_info0 | +// |---------------------------------| +// | bucket_info1 | bucket_info2 | +// | bucket_info3 ... | +// | .... | table_end_info | +// |---------------------------------| +// | entry0 | +// | entry1 | +// | entry2 | +// | | +// | ... | +// ----------------------------------- +// +// The size of the bucket_info table is 'num_buckets + 1'. Each entry of the +// bucket_info table is a 32-bit encoding of the bucket type and bucket offset, +// with the type in the left-most 2-bit and offset in the remaining 30-bit. +// The last entry is a special type. It contains the offset of the last +// bucket end. We use that information when traversing the compact table. +// +// There are two types of buckets, regular buckets and compact buckets. The +// compact buckets have '01' in their highest 2-bit, and regular buckets have +// '00' in their highest 2-bit. +// +// For normal buckets, each symbol's entry is 8 bytes in the table[]: +// juint hash; /* symbol hash */ +// juint offset; /* Symbol* sym = (Symbol*)(base_address + offset) */ +// +// For compact buckets, each entry has only the 4-byte 'offset' in the table[]. +// +// See CompactHashtable::lookup() for how the table is searched at runtime. +// See CompactHashtableWriter::dump() for how the table is written at CDS +// dump time. +// +template class CompactHashtable VALUE_OBJ_CLASS_SPEC { + uintx _base_address; + juint _entry_count; + juint _bucket_count; + juint _table_end_offset; + juint* _buckets; + + inline bool equals(T entry, const char* name, int len) { + if (entry->equals(name, len)) { + assert(entry->refcount() == -1, "must be shared"); + return true; + } else { + return false; + } + } + +public: + CompactHashtable() { + _entry_count = 0; + _bucket_count = 0; + _table_end_offset = 0; + _buckets = 0; + } + const char* init(const char *buffer); + + // Lookup an entry from the compact table + inline T lookup(const N* name, unsigned int hash, int len) { + if (_entry_count > 0) { + assert(!DumpSharedSpaces, "run-time only"); + int index = hash % _bucket_count; + juint bucket_info = _buckets[index]; + juint bucket_offset = BUCKET_OFFSET(bucket_info); + int bucket_type = BUCKET_TYPE(bucket_info); + juint* bucket = _buckets + bucket_offset; + juint* bucket_end = _buckets; + + if (bucket_type == COMPACT_BUCKET_TYPE) { + // the compact bucket has one entry with symbol offset only + T entry = (T)((void*)(_base_address + bucket[0])); + if (equals(entry, name, len)) { + return entry; + } + } else { + // This is a regular bucket, which has more than one + // entries. Each entry is a pair of symbol (hash, offset). + // Seek until the end of the bucket. + bucket_end += BUCKET_OFFSET(_buckets[index + 1]); + while (bucket < bucket_end) { + unsigned int h = (unsigned int)(bucket[0]); + if (h == hash) { + juint offset = bucket[1]; + T entry = (T)((void*)(_base_address + offset)); + if (equals(entry, name, len)) { + return entry; + } + } + bucket += 2; + } + } + } + return NULL; + } +}; + +//////////////////////////////////////////////////////////////////////// +// +// Read/Write the contents of a hashtable textual dump (created by +// SymbolTable::dump). +// Because the dump file may be big (hundred of MB in extreme cases), +// we use mmap for fast access when reading it. +// +class HashtableTextDump VALUE_OBJ_CLASS_SPEC { + int _fd; + const char* _base; + const char* _p; + const char* _end; + const char* _filename; + size_t _size; +public: + HashtableTextDump(const char* filename); + ~HashtableTextDump(); + + void quit(const char* err, const char* msg); + + inline int remain() { + return (int)(_end - _p); + } + + void corrupted(const char *p); + + inline void corrupted_if(bool cond) { + if (cond) { + corrupted(_p); + } + } + + bool skip_newline(); + int skip(char must_be_char); + void skip_past(char c); + void check_version(const char* ver); + + inline int get_num(char delim) { + const char* p = _p; + const char* end = _end; + int num = 0; + + while (p < end) { + char c = *p ++; + if ('0' <= c && c <= '9') { + num = num * 10 + (c - '0'); + } else if (c == delim) { + _p = p; + return num; + } else { + corrupted(p-1); + } + } + corrupted(_end); + ShouldNotReachHere(); + return 0; + } + + int scan_prefix(); + int scan_prefix2(); + + jchar unescape(const char* from, const char* end, int count); + void get_utf8(char* utf8_buffer, int utf8_length); + static void put_utf8(outputStream* st, const char* utf8_string, int utf8_length); +}; + +/////////////////////////////////////////////////////////////////////// +// +// jcmd command support for symbol table and string table dumping: +// VM.symboltable -verbose: for dumping the symbol table +// VM.stringtable -verbose: for dumping the string table +// +class VM_DumpHashtable : public VM_Operation { +private: + outputStream* _out; + int _which; + bool _verbose; +public: + enum { + DumpSymbols = 1 << 0, + DumpStrings = 1 << 1, + DumpSysDict = 1 << 2 // not implemented yet + }; + VM_DumpHashtable(outputStream* out, int which, bool verbose) { + _out = out; + _which = which; + _verbose = verbose; + } + + virtual VMOp_Type type() const { return VMOp_DumpHashtable; } + + virtual void doit() { + switch (_which) { + case DumpSymbols: + SymbolTable::dump(_out, _verbose); + break; + case DumpStrings: + StringTable::dump(_out, _verbose); + break; + default: + ShouldNotReachHere(); + } + } +}; + +class SymboltableDCmd : public DCmdWithParser { +protected: + DCmdArgument _verbose; +public: + SymboltableDCmd(outputStream* output, bool heap); + static const char* name() { + return "VM.symboltable"; + } + static const char* description() { + return "Dump symbol table."; + } + static const char* impact() { + return "Medium: Depends on Java content."; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments(); + virtual void execute(DCmdSource source, TRAPS); +}; + +class StringtableDCmd : public DCmdWithParser { +protected: + DCmdArgument _verbose; +public: + StringtableDCmd(outputStream* output, bool heap); + static const char* name() { + return "VM.stringtable"; + } + static const char* description() { + return "Dump string table."; + } + static const char* impact() { + return "Medium: Depends on Java content."; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments(); + virtual void execute(DCmdSource source, TRAPS); +}; + +#endif // SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP diff --git a/hotspot/src/share/vm/classfile/stringTable.cpp b/hotspot/src/share/vm/classfile/stringTable.cpp index 334fe7cbd39..7d2a4f93ef3 100644 --- a/hotspot/src/share/vm/classfile/stringTable.cpp +++ b/hotspot/src/share/vm/classfile/stringTable.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" @@ -379,8 +380,36 @@ void StringTable::verify() { } } -void StringTable::dump(outputStream* st) { - the_table()->dump_table(st, "StringTable"); +void StringTable::dump(outputStream* st, bool verbose) { + if (!verbose) { + the_table()->dump_table(st, "StringTable"); + } else { + Thread* THREAD = Thread::current(); + st->print_cr("VERSION: 1.1"); + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + oop s = p->literal(); + typeArrayOop value = java_lang_String::value(s); + int offset = java_lang_String::offset(s); + int length = java_lang_String::length(s); + + if (length <= 0) { + st->print("%d: ", length); + } else { + ResourceMark rm(THREAD); + jchar* chars = (jchar*)value->char_at_addr(offset); + int utf8_length = UNICODE::utf8_length(chars, length); + char* utf8_string = NEW_RESOURCE_ARRAY(char, utf8_length + 1); + UNICODE::convert_to_utf8(chars, length, utf8_string); + + st->print("%d: ", utf8_length); + HashtableTextDump::put_utf8(st, utf8_string, utf8_length); + } + st->cr(); + } + } + } } StringTable::VerifyRetTypes StringTable::compare_entries( @@ -558,3 +587,28 @@ void StringTable::rehash_table() { _needs_rehashing = false; _the_table = new_table; } + +// Utility for dumping strings +StringtableDCmd::StringtableDCmd(outputStream* output, bool heap) : + DCmdWithParser(output, heap), + _verbose("-verbose", "Dump the content of each string in the table", + "BOOLEAN", false, "false") { + _dcmdparser.add_dcmd_option(&_verbose); +} + +void StringtableDCmd::execute(DCmdSource source, TRAPS) { + VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpStrings, + _verbose.value()); + VMThread::execute(&dumper); +} + +int StringtableDCmd::num_arguments() { + ResourceMark rm; + StringtableDCmd* dcmd = new StringtableDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} diff --git a/hotspot/src/share/vm/classfile/stringTable.hpp b/hotspot/src/share/vm/classfile/stringTable.hpp index e8f42834d07..72f69e93381 100644 --- a/hotspot/src/share/vm/classfile/stringTable.hpp +++ b/hotspot/src/share/vm/classfile/stringTable.hpp @@ -118,7 +118,7 @@ public: // Debugging static void verify(); - static void dump(outputStream* st); + static void dump(outputStream* st, bool verbose=false); enum VerifyMesgModes { _verify_quietly = 0, diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 8ffb17f8f71..4df696f74c7 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -47,6 +48,9 @@ SymbolTable* SymbolTable::_the_table = NULL; // Static arena for symbols that are not deallocated Arena* SymbolTable::_arena = NULL; bool SymbolTable::_needs_rehashing = false; +bool SymbolTable::_lookup_shared_first = false; + +CompactHashtable SymbolTable::_shared_table; Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { assert (len <= Symbol::max_length(), "should be checked by caller"); @@ -186,8 +190,8 @@ void SymbolTable::rehash_table() { // Lookup a symbol in a bucket. -Symbol* SymbolTable::lookup(int index, const char* name, - int len, unsigned int hash) { +Symbol* SymbolTable::lookup_dynamic(int index, const char* name, + int len, unsigned int hash) { int count = 0; for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { count++; // count all entries in this bucket, not just ones with same hash @@ -207,6 +211,34 @@ Symbol* SymbolTable::lookup(int index, const char* name, return NULL; } +Symbol* SymbolTable::lookup_shared(const char* name, + int len, unsigned int hash) { + return _shared_table.lookup(name, hash, len); +} + +Symbol* SymbolTable::lookup(int index, const char* name, + int len, unsigned int hash) { + Symbol* sym; + if (_lookup_shared_first) { + sym = lookup_shared(name, len, hash); + if (sym != NULL) { + return sym; + } + _lookup_shared_first = false; + return lookup_dynamic(index, name, len, hash); + } else { + sym = lookup_dynamic(index, name, len, hash); + if (sym != NULL) { + return sym; + } + sym = lookup_shared(name, len, hash); + if (sym != NULL) { + _lookup_shared_first = true; + } + return sym; + } +} + // Pick hashing algorithm. unsigned int SymbolTable::hash_symbol(const char* s, int len) { return use_alternate_hashcode() ? @@ -483,10 +515,56 @@ void SymbolTable::verify() { } } -void SymbolTable::dump(outputStream* st) { - the_table()->dump_table(st, "SymbolTable"); +void SymbolTable::dump(outputStream* st, bool verbose) { + if (!verbose) { + the_table()->dump_table(st, "SymbolTable"); + } else { + st->print_cr("VERSION: 1.0"); + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + Symbol* s = (Symbol*)(p->literal()); + const char* utf8_string = (const char*)s->bytes(); + int utf8_length = s->utf8_length(); + st->print("%d %d: ", utf8_length, s->refcount()); + HashtableTextDump::put_utf8(st, utf8_string, utf8_length); + st->cr(); + } + } + } } +bool SymbolTable::copy_compact_table(char** top, char*end) { +#if INCLUDE_CDS + CompactHashtableWriter ch_table("symbol", the_table()->number_of_entries(), + &MetaspaceShared::stats()->symbol); + if (*top + ch_table.get_required_bytes() > end) { + // not enough space left + return false; + } + + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + Symbol* s = (Symbol*)(p->literal()); + unsigned int fixed_hash = hash_symbol((char*)s->bytes(), s->utf8_length()); + assert(fixed_hash == p->hash(), "must not rehash during dumping"); + ch_table.add(fixed_hash, s); + } + } + + char* old_top = *top; + ch_table.dump(top, end); + + *top = (char*)align_pointer_up(*top, sizeof(void*)); +#endif + return true; +} + +const char* SymbolTable::init_shared_table(const char* buffer) { + const char* end = _shared_table.init(buffer); + return (const char*)align_pointer_up(end, sizeof(void*)); +} //--------------------------------------------------------------------------- // Non-product code @@ -574,3 +652,29 @@ void SymbolTable::print() { } } #endif // PRODUCT + + +// Utility for dumping symbols +SymboltableDCmd::SymboltableDCmd(outputStream* output, bool heap) : + DCmdWithParser(output, heap), + _verbose("-verbose", "Dump the content of each symbol in the table", + "BOOLEAN", false, "false") { + _dcmdparser.add_dcmd_option(&_verbose); +} + +void SymboltableDCmd::execute(DCmdSource source, TRAPS) { + VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpSymbols, + _verbose.value()); + VMThread::execute(&dumper); +} + +int SymboltableDCmd::num_arguments() { + ResourceMark rm; + SymboltableDCmd* dcmd = new SymboltableDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp index 81f3c085a00..4095e6e7615 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.hpp +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp @@ -73,6 +73,8 @@ class TempNewSymbol : public StackObj { operator Symbol*() { return _temp; } }; +template class CompactHashtable; + class SymbolTable : public RehashableHashtable { friend class VMStructs; friend class ClassFileParser; @@ -83,11 +85,15 @@ private: // Set if one bucket is out of balance due to hash algorithm deficiency static bool _needs_rehashing; + static bool _lookup_shared_first; // For statistics static int _symbols_removed; static int _symbols_counted; + // shared symbol table. + static CompactHashtable _shared_table; + Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F // Adding elements @@ -106,6 +112,8 @@ private: add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD); } + static Symbol* lookup_shared(const char* name, int len, unsigned int hash); + Symbol* lookup_dynamic(int index, const char* name, int len, unsigned int hash); Symbol* lookup(int index, const char* name, int len, unsigned int hash); SymbolTable() @@ -144,20 +152,6 @@ public: initialize_symbols(symbol_alloc_arena_size); } - static void create_table(HashtableBucket* t, int length, - int number_of_entries) { - assert(_the_table == NULL, "One symbol table allowed."); - - // If CDS archive used a different symbol table size, use that size instead - // which is better than giving an error. - SymbolTableSize = length/bucket_size(); - - _the_table = new SymbolTable(t, number_of_entries); - // if CDS give symbol table a default arena size since most symbols - // are already allocated in the shared misc section. - initialize_symbols(); - } - static unsigned int hash_symbol(const char* s, int len); static Symbol* lookup(const char* name, int len, TRAPS); @@ -230,18 +224,12 @@ public: // Debugging static void verify(); - static void dump(outputStream* st); + static void dump(outputStream* st, bool verbose=false); + static void read(const char* filename, TRAPS); // Sharing - static void copy_buckets(char** top, char*end) { - the_table()->Hashtable::copy_buckets(top, end); - } - static void copy_table(char** top, char*end) { - the_table()->Hashtable::copy_table(top, end); - } - static void reverse(void* boundary = NULL) { - the_table()->Hashtable::reverse(boundary); - } + static bool copy_compact_table(char** top, char* end); + static const char* init_shared_table(const char* buffer); // Rehash the symbol table if it gets out of balance static void rehash_table(); diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 26729be6efd..b66061e5f6d 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -48,6 +48,8 @@ int MetaspaceShared::_max_alignment = 0; ReservedSpace* MetaspaceShared::_shared_rs = NULL; +MetaspaceSharedStats MetaspaceShared::_stats; + bool MetaspaceShared::_link_classes_made_progress; bool MetaspaceShared::_check_classes_made_progress; bool MetaspaceShared::_has_error_classes; @@ -259,7 +261,7 @@ public: #define SHAREDSPACE_OBJ_TYPES_DO(f) \ METASPACE_OBJ_TYPES_DO(f) \ f(SymbolHashentry) \ - f(SymbolBuckets) \ + f(SymbolBucket) \ f(Other) #define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type, @@ -315,18 +317,16 @@ void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all int other_bytes = md_all + mc_all; // Calculate size of data that was not allocated by Metaspace::allocate() - int symbol_count = _counts[RO][MetaspaceObj::SymbolType]; - int symhash_bytes = symbol_count * sizeof (HashtableEntry); - int symbuck_count = SymbolTable::the_table()->table_size(); - int symbuck_bytes = symbuck_count * sizeof(HashtableBucket); + MetaspaceSharedStats *stats = MetaspaceShared::stats(); - _counts[RW][SymbolHashentryType] = symbol_count; - _bytes [RW][SymbolHashentryType] = symhash_bytes; - other_bytes -= symhash_bytes; + // symbols + _counts[RW][SymbolHashentryType] = stats->symbol.hashentry_count; + _bytes [RW][SymbolHashentryType] = stats->symbol.hashentry_bytes; + other_bytes -= stats->symbol.hashentry_bytes; - _counts[RW][SymbolBucketsType] = symbuck_count; - _bytes [RW][SymbolBucketsType] = symbuck_bytes; - other_bytes -= symbuck_bytes; + _counts[RW][SymbolBucketType] = stats->symbol.bucket_count; + _bytes [RW][SymbolBucketType] = stats->symbol.bucket_bytes; + other_bytes -= stats->symbol.bucket_bytes; // TODO: count things like dictionary, vtable, etc _bytes[RW][OtherType] = other_bytes; @@ -424,6 +424,13 @@ public: VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } void doit(); // outline because gdb sucks + +private: + void handle_misc_data_space_failure(bool success) { + if (!success) { + report_out_of_shared_space(SharedMiscData); + } + } }; // class VM_PopulateDumpSharedSpace @@ -517,9 +524,8 @@ void VM_PopulateDumpSharedSpace::doit() { // buckets first [read-write], then copy the linked lists of entries // [read-only]. - SymbolTable::reverse(md_top); NOT_PRODUCT(SymbolTable::verify()); - SymbolTable::copy_buckets(&md_top, md_end); + handle_misc_data_space_failure(SymbolTable::copy_compact_table(&md_top, md_end)); SystemDictionary::reverse(); SystemDictionary::copy_buckets(&md_top, md_end); @@ -528,7 +534,6 @@ void VM_PopulateDumpSharedSpace::doit() { ClassLoader::copy_package_info_buckets(&md_top, md_end); ClassLoader::verify(); - SymbolTable::copy_table(&md_top, md_end); SystemDictionary::copy_table(&md_top, md_end); ClassLoader::verify(); ClassLoader::copy_package_info_table(&md_top, md_end); @@ -1000,17 +1005,12 @@ void MetaspaceShared::initialize_shared_spaces() { buffer += sizeof(intptr_t); buffer += vtable_size; - // Create the symbol table using the bucket array at this spot in the - // misc data space. Since the symbol table is often modified, this - // region (of mapped pages) will be copy-on-write. + // Create the shared symbol table using the bucket array at this spot in the + // misc data space. (Todo: move this to read-only space. Currently + // this is mapped copy-on-write but will never be written into). - int symbolTableLen = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - int number_of_entries = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - SymbolTable::create_table((HashtableBucket*)buffer, symbolTableLen, - number_of_entries); - buffer += symbolTableLen; + buffer = (char*)SymbolTable::init_shared_table(buffer); + SymbolTable::create_table(); // Create the shared dictionary using the bucket array at this spot in // the misc data space. Since the shared dictionary table is never @@ -1019,7 +1019,7 @@ void MetaspaceShared::initialize_shared_spaces() { int sharedDictionaryLen = *(intptr_t*)buffer; buffer += sizeof(intptr_t); - number_of_entries = *(intptr_t*)buffer; + int number_of_entries = *(intptr_t*)buffer; buffer += sizeof(intptr_t); SystemDictionary::set_shared_dictionary((HashtableBucket*)buffer, sharedDictionaryLen, @@ -1041,18 +1041,10 @@ void MetaspaceShared::initialize_shared_spaces() { ClassLoader::verify(); // The following data in the shared misc data region are the linked - // list elements (HashtableEntry objects) for the symbol table, string - // table, and shared dictionary. The heap objects referred to by the - // symbol table, string table, and shared dictionary are permanent and - // unmovable. Since new entries added to the string and symbol tables - // are always added at the beginning of the linked lists, THESE LINKED - // LIST ELEMENTS ARE READ-ONLY. + // list elements (HashtableEntry objects) for the shared dictionary + // and package info table. - int len = *(intptr_t*)buffer; // skip over symbol table entries - buffer += sizeof(intptr_t); - buffer += len; - - len = *(intptr_t*)buffer; // skip over shared dictionary entries + int len = *(intptr_t*)buffer; // skip over shared dictionary entries buffer += sizeof(intptr_t); buffer += len; diff --git a/hotspot/src/share/vm/memory/metaspaceShared.hpp b/hotspot/src/share/vm/memory/metaspaceShared.hpp index e6e2c9a353e..85bf0e4a303 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp @@ -24,6 +24,7 @@ #ifndef SHARE_VM_MEMORY_METASPACE_SHARED_HPP #define SHARE_VM_MEMORY_METASPACE_SHARED_HPP +#include "classfile/compactHashtable.hpp" #include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "runtime/virtualspace.hpp" @@ -45,12 +46,21 @@ class FileMapInfo; +class MetaspaceSharedStats VALUE_OBJ_CLASS_SPEC { +public: + MetaspaceSharedStats() { + memset(this, 0, sizeof(*this)); + } + CompactHashtableStats symbol; +}; + // Class Data Sharing Support class MetaspaceShared : AllStatic { // CDS support static ReservedSpace* _shared_rs; static int _max_alignment; + static MetaspaceSharedStats _stats; static bool _link_classes_made_progress; static bool _check_classes_made_progress; static bool _has_error_classes; @@ -123,6 +133,10 @@ class MetaspaceShared : AllStatic { char** mc_top, char* mc_end); static void serialize(SerializeClosure* sc); + static MetaspaceSharedStats* stats() { + return &_stats; + } + // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private if // sharing is enabled. Simply returns true if sharing is not enabled diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 61396a28c2b..865f6b0c23c 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1176,9 +1176,7 @@ bool universe_post_init() { MemoryService::set_universe_heap(Universe::_collectedHeap); #if INCLUDE_CDS - if (UseSharedSpaces) { - SharedClassUtil::initialize(CHECK_false); - } + SharedClassUtil::initialize(CHECK_false); #endif return true; } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 436542618ac..4ea7f2fb467 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3782,6 +3782,9 @@ class CommandLineFlags { NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \ "Address to allocate shared memory region for class data") \ \ + product(uintx, SharedSymbolTableBucketSize, 4, \ + "Average number of symbols per bucket in shared table") \ + \ diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false, \ "Do not quit -Xshare:dump even if we encounter unverifiable " \ "classes. Just exclude them from the shared dictionary.") \ diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp index ae710ebf782..36353521525 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.hpp +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp @@ -100,6 +100,7 @@ template(RotateGCLog) \ template(WhiteBoxOperation) \ template(ClassLoaderStatsOperation) \ + template(DumpHashtable) \ template(MarkActiveNMethods) \ template(PrintCompileQueue) \ template(PrintCodeList) \ diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 8f8309f97f7..a1853ea2464 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderStats.hpp" +#include "classfile/compactHashtable.hpp" #include "gc_implementation/shared/vmGCOperations.hpp" #include "runtime/javaCalls.hpp" #include "runtime/os.hpp" @@ -56,6 +57,8 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // INCLUDE_SERVICES DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); diff --git a/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java new file mode 100644 index 00000000000..0bad2c31bc9 --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8059510 + * @summary Test jcmd VM.symboltable and VM.stringtable options + * @library /testlibrary + * @run main/othervm -XX:+UnlockDiagnosticVMOptions DumpSymbolAndStringTable + */ + +import com.oracle.java.testlibrary.*; + +public class DumpSymbolAndStringTable { + public static void main(String[] args) throws Exception { + // Grab my own PID + String pid = Integer.toString(ProcessTools.getProcessId()); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.symboltable", "-verbose"}); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("24 2: DumpSymbolAndStringTable\n"); + } catch (RuntimeException e) { + output.shouldContain("Unknown diagnostic command"); + } + + pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.stringtable", "-verbose"}); + output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("16: java.lang.String\n"); + } catch (RuntimeException e) { + output.shouldContain("Unknown diagnostic command"); + } + } +} diff --git a/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java new file mode 100644 index 00000000000..1c71e4b739c --- /dev/null +++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8059510 + * @summary Test SharedSymbolTableBucketSize option + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class SharedSymbolTableBucketSize { + public static void main(String[] args) throws Exception { + int bucket_size = 8; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xshare:dump", "-XX:+PrintSharedSpaces", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", + "-XX:SharedSymbolTableBucketSize=" + Integer.valueOf(bucket_size)); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + + String s = output.firstMatch("Average bucket size : .*"); + Float f = Float.parseFloat(s.substring(25)); + int size = Math.round(f); + if (size != bucket_size) { + throw new Exception("FAILED: incorrect bucket size " + size + + ", expect " + bucket_size); + } + + + // Invalid SharedSymbolTableBucketSize input + String input[] = {"-XX:SharedSymbolTableBucketSize=-1", + "-XX:SharedSymbolTableBucketSize=2.5"}; + for (int i = 0; i < input.length; i++) { + pb = ProcessTools.createJavaProcessBuilder( + "-Xshare:dump", "-XX:+PrintSharedSpaces", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", + input[i]); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Improperly specified VM option"); + } + } +} From feb09bc11887a257c890107ecab11a38a7f39493 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 18 Dec 2014 16:15:21 -0500 Subject: [PATCH 22/72] 8067713: Move clean_weak_method_links for redefinition out of class unloading Do this work during class redefinition, only verify clean during class unloading in debug mode. Reviewed-by: sspitsyn, roland, kbarrett --- .../share/vm/classfile/classLoaderData.cpp | 9 +------ hotspot/src/share/vm/oops/instanceKlass.cpp | 17 +++++++------ hotspot/src/share/vm/oops/methodData.cpp | 22 ++++++++++++++--- hotspot/src/share/vm/oops/methodData.hpp | 4 ++++ .../share/vm/prims/jvmtiRedefineClasses.cpp | 24 +++++++++++++++++-- .../share/vm/prims/jvmtiRedefineClasses.hpp | 6 +++++ 6 files changed, 62 insertions(+), 20 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index 96e48340847..44e152b8384 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -786,17 +786,12 @@ void ClassLoaderDataGraph::clean_metaspaces() { MetadataOnStackMark md_on_stack(has_redefined_a_class); if (has_redefined_a_class) { - // purge_previous_versions also cleans weak method links. Because - // one method's MDO can reference another method from another - // class loader, we need to first clean weak method links for all - // class loaders here. Below, we can then free redefined methods - // for all class loaders. for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { data->classes_do(InstanceKlass::purge_previous_versions); } } - // Need to purge the previous version before deallocating. + // Should purge the previous version before deallocating. free_deallocate_lists(); } @@ -834,8 +829,6 @@ void ClassLoaderDataGraph::post_class_unload_events(void) { void ClassLoaderDataGraph::free_deallocate_lists() { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - // We need to keep this data until InstanceKlass::purge_previous_version has been - // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces. cld->free_deallocate_list(); } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 40c2e1e039d..cf663ea72d1 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -3543,11 +3543,12 @@ void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { ("purge: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(), method->signature()->as_C_string(), j, version)); +#ifdef ASSERT if (method->method_data() != NULL) { - // Clean out any weak method links for running methods - // (also should include not EMCP methods) - method->method_data()->clean_weak_method_links(); + // Verify MethodData for running methods don't refer to old methods. + method->method_data()->verify_clean_weak_method_links(); } +#endif // ASSERT } } } @@ -3561,15 +3562,17 @@ void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { deleted_count)); } - // Clean MethodData of this class's methods so they don't refer to +#ifdef ASSERT + // Verify clean MethodData for this class's methods, e.g. they don't refer to // old methods that are no longer running. Array* methods = ik->methods(); int num_methods = methods->length(); - for (int index2 = 0; index2 < num_methods; ++index2) { - if (methods->at(index2)->method_data() != NULL) { - methods->at(index2)->method_data()->clean_weak_method_links(); + for (int index = 0; index < num_methods; ++index) { + if (methods->at(index)->method_data() != NULL) { + methods->at(index)->method_data()->verify_clean_weak_method_links(); } } +#endif // ASSERT } void InstanceKlass::mark_newly_obsolete_methods(Array* old_methods, diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp index b1cfeecbef9..ef215581df1 100644 --- a/hotspot/src/share/vm/oops/methodData.cpp +++ b/hotspot/src/share/vm/oops/methodData.cpp @@ -1283,6 +1283,11 @@ ProfileData* MethodData::bci_to_extra_data(int bci, Method* m, bool create_if_mi DataLayout::compute_size_in_bytes(SpeculativeTrapData::static_cell_count()), "code needs to be adjusted"); + // Do not create one of these if method has been redefined. + if (m != NULL && m->is_old()) { + return NULL; + } + DataLayout* dp = extra_data_base(); DataLayout* end = args_data_limit(); @@ -1554,9 +1559,7 @@ public: class CleanExtraDataMethodClosure : public CleanExtraDataClosure { public: CleanExtraDataMethodClosure() {} - bool is_live(Method* m) { - return !m->is_old() || m->on_stack(); - } + bool is_live(Method* m) { return !m->is_old(); } }; @@ -1658,3 +1661,16 @@ void MethodData::clean_weak_method_links() { clean_extra_data(&cl); verify_extra_data_clean(&cl); } + +#ifdef ASSERT +void MethodData::verify_clean_weak_method_links() { + for (ProfileData* data = first_data(); + is_valid(data); + data = next_data(data)) { + data->verify_clean_weak_method_links(); + } + + CleanExtraDataMethodClosure cl; + verify_extra_data_clean(&cl); +} +#endif // ASSERT diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 49768dd001e..e91cffb8375 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -254,6 +254,7 @@ public: // Redefinition support void clean_weak_method_links(); + DEBUG_ONLY(void verify_clean_weak_method_links();) }; @@ -511,6 +512,7 @@ public: // Redefinition support virtual void clean_weak_method_links() {} + DEBUG_ONLY(virtual void verify_clean_weak_method_links() {}) // CI translation: ProfileData can represent both MethodDataOop data // as well as CIMethodData data. This function is provided for translating @@ -1971,6 +1973,7 @@ public: } void set_method(Method* m) { + assert(!m->is_old(), "cannot add old methods"); set_intptr_at(speculative_trap_method, (intptr_t)m); } @@ -2480,6 +2483,7 @@ public: void clean_method_data(BoolObjectClosure* is_alive); void clean_weak_method_links(); + DEBUG_ONLY(void verify_clean_weak_method_links();) Mutex* extra_data_lock() { return &_extra_data_lock; } }; diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 9335857ee56..a4c76771028 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -148,6 +148,10 @@ void VM_RedefineClasses::doit() { _scratch_classes[i] = NULL; } + // Clean out MethodData pointing to old Method* + MethodDataCleaner clean_weak_method_links; + ClassLoaderDataGraph::classes_do(&clean_weak_method_links); + // Disable any dependent concurrent compilations SystemDictionary::notice_modification(); @@ -155,8 +159,8 @@ void VM_RedefineClasses::doit() { // See jvmtiExport.hpp for detailed explanation. JvmtiExport::set_has_redefined_a_class(); -// check_class() is optionally called for product bits, but is -// always called for non-product bits. + // check_class() is optionally called for product bits, but is + // always called for non-product bits. #ifdef PRODUCT if (RC_TRACE_ENABLED(0x00004000)) { #endif @@ -3445,6 +3449,22 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { } } +// Clean method data for this class +void VM_RedefineClasses::MethodDataCleaner::do_klass(Klass* k) { + if (k->oop_is_instance()) { + InstanceKlass *ik = InstanceKlass::cast(k); + // Clean MethodData of this class's methods so they don't refer to + // old methods that are no longer running. + Array* methods = ik->methods(); + int num_methods = methods->length(); + for (int index = 0; index < num_methods; ++index) { + if (methods->at(index)->method_data() != NULL) { + methods->at(index)->method_data()->clean_weak_method_links(); + } + } + } +} + void VM_RedefineClasses::update_jmethod_ids() { for (int j = 0; j < _matching_methods_length; ++j) { Method* old_method = _matching_old_methods[j]; diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp index 8394f5f50a3..8cb433cdc5e 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp @@ -511,6 +511,12 @@ class VM_RedefineClasses: public VM_Operation { void do_klass(Klass* k); }; + // Clean MethodData out + class MethodDataCleaner : public KlassClosure { + public: + MethodDataCleaner() {} + void do_klass(Klass* k); + }; public: VM_RedefineClasses(jint class_count, const jvmtiClassDefinition *class_defs, From f1e461b61ec5d7667230359d619e72dcd80ccce2 Mon Sep 17 00:00:00 2001 From: Katja Kantserova Date: Fri, 19 Dec 2014 13:13:11 +0100 Subject: [PATCH 23/72] 6977426: sun/tools tests can intermittently fail to find app's Java pid Reviewed-by: dfuchs, jbachorik, egahlin, sjiang --- jdk/test/TEST.groups | 3 +- .../util/logging/AnonLoggerWeakRefLeak.java | 92 ----- .../util/logging/AnonLoggerWeakRefLeak.sh | 254 -------------- .../java/util/logging/LoggerWeakRefLeak.java | 102 ------ .../java/util/logging/LoggerWeakRefLeak.sh | 254 -------------- .../util/logging/TestLoggerWeakRefLeak.java | 164 +++++++++ jdk/test/sun/tools/common/CommonTests.sh | 314 ------------------ 7 files changed, 165 insertions(+), 1018 deletions(-) delete mode 100644 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java delete mode 100644 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh delete mode 100644 jdk/test/java/util/logging/LoggerWeakRefLeak.java delete mode 100644 jdk/test/java/util/logging/LoggerWeakRefLeak.sh create mode 100644 jdk/test/java/util/logging/TestLoggerWeakRefLeak.java delete mode 100644 jdk/test/sun/tools/common/CommonTests.sh diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index b46e5747283..4d4705c2ba4 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -421,8 +421,7 @@ needs_jdk = \ java/util/Collections/EmptyIterator.java \ java/util/concurrent/locks/Lock/TimedAcquireLeak.java \ java/util/jar/JarInputStream/ExtraFileInMetaInf.java \ - java/util/logging/AnonLoggerWeakRefLeak.sh \ - java/util/logging/LoggerWeakRefLeak.sh \ + java/util/logging/TestLoggerWeakRefLeak.java \ java/util/zip/3GBZipFiles.sh \ jdk/lambda/FDTest.java \ jdk/lambda/separate/Compiler.java \ diff --git a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java b/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java deleted file mode 100644 index ed72e7f4110..00000000000 --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010, 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.logging.*; - -public class AnonLoggerWeakRefLeak extends SimpleApplication { - // The test driver script will allow this program to run until we - // reach DEFAULT_LOOP_TIME or a decrease in instance counts is - // observed. For this particular WeakReference leak, the count - // was always observed to be increasing so if we get a decreasing - // count, then the leak is fixed in the bits being tested. - // Two minutes has been enough time to observe a decrease in - // fixed bits on overloaded systems, but the test will likely - // finish more quickly. - public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - - // execute the AnonLoggerWeakRefLeak app work - public void doMyAppWork(String[] args) throws Exception { - int loop_time = 0; - int max_loop_time = DEFAULT_LOOP_TIME; - - // args[0] is the port-file - if (args.length < 2) { - System.out.println("INFO: using default time of " - + max_loop_time + " seconds."); - } else { - try { - max_loop_time = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - throw new RuntimeException("Error: '" + args[1] - + "': is not a valid seconds value."); - } - } - - long count = 0; - long now = 0; - long startTime = System.currentTimeMillis(); - - while (now < (startTime + (max_loop_time * 1000))) { - if ((count % 1000) == 0) { - // Print initial call count to let caller know that - // we're up and running and then periodically - System.out.println("INFO: call count = " + count); - } - - for (int i = 0; i < 100; i++) { - // this Logger call is leaking a WeakReference in Logger.kids - java.util.logging.Logger.getAnonymousLogger(); - count++; - } - - try { - // delay for 1/10 of a second to avoid CPU saturation - Thread.sleep(100); - } catch (InterruptedException ie) { - // ignore any exceptions - } - - now = System.currentTimeMillis(); - } - - System.out.println("INFO: final loop count = " + count); - } - - public static void main(String[] args) throws Exception { - AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); - - SimpleApplication.setMyApp(myApp); - - SimpleApplication.main(args); - } -} diff --git a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh b/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh deleted file mode 100644 index fc1aece9ebd..00000000000 --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6942989 -# @summary Check for WeakReference leak in anonymous Logger objects -# @author Daniel D. Daugherty -# -# @library ../../../sun/tools/common -# @build SimpleApplication ShutdownSimpleApplication -# @build AnonLoggerWeakRefLeak -# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh - -# The timeout is: 2 minutes for infrastructure and 2 minutes for the test -# - -. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh -. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh - - -TEST_NAME="AnonLoggerWeakRefLeak" -TARGET_CLASS="java\.lang\.ref\.WeakReference" - - -# MAIN begins here -# - -seconds= -if [ "$#" -gt 0 ]; then - seconds="$1" -fi - -# see if this version of jmap supports the '-histo:live' option -jmap_option="-histo:live" -set +e -"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 -status="$?" -set -e -if [ "$status" != 0 ]; then - # usage message doesn't show ':live' option - - if $isWindows; then - # If SA isn't present, then jmap gives a different usage message - # that doesn't show the ':live' option. However, that's a bug that - # is covered by 6971851 so we try using the option just to be sure. - # For some reason, this problem has only been seen on OpenJDK6 on - # Windows. Not sure why. - set +e - # Note: Don't copy this code to try probing process 0 on Linux; it - # will kill the process group in strange ways. - "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - # Usage message generated so flag the problem. - status=1 - else - # No usage message so clear the flag. - status=0 - fi - fi - - if [ "$status" != 0 ]; then - echo "WARNING: 'jmap $jmap_option' is not supported on this platform" - echo "WARNING: so this test cannot work reliably. Aborting!" - exit 0 - fi -fi - -# Start application and use TEST_NAME.port for coordination -startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds - -finished_early=false - -decreasing_cnt=0 -increasing_cnt=0 -loop_cnt=0 -prev_instance_cnt=0 - -MAX_JMAP_TRY_CNT=10 -jmap_retry_cnt=0 -loop_cnt_on_retry=0 - -while true; do - # see if the target process has finished its run and bail if it has - set +e - grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - break - fi - - # Output format for 'jmap -histo' in JDK1.5.0: - # - # <#bytes> <#instances> - # - # Output format for 'jmap -histo:live': - # - # : <#instances> <#bytes> - # - set +e - "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 - status="$?" - set -e - - if [ "$status" != 0 ]; then - echo "INFO: jmap exited with exit code = $status" - - # There are intermittent jmap failures; see 6498448. - # - # So far the following have been observed in a jmap call - # that was not in a race with target process termination: - # - # (Solaris specific, 2nd sample) - # : Unable to open door: target process not responding or HotSpot VM not loaded - # The -F option can be used when the target process is not responding - # - # (on Solaris so far) - # java.io.IOException - # - # (on Solaris so far, 1st sample) - # : Permission denied - # - sed 's/^/INFO: /' "$TEST_NAME.jmap" - - if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then - # loop count hasn't changed - jmap_retry_cnt=`expr $jmap_retry_cnt + 1` - else - # loop count has changed so remember it - jmap_retry_cnt=1 - loop_cnt_on_retry="$loop_cnt" - fi - - # This is '-ge' because we have the original attempt plus - # MAX_JMAP_TRY_CNT - 1 retries. - if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then - echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ - "without making any progress." - echo "FAIL: jmap is unable to take any samples." >&2 - killApplication - exit 2 - fi - - # short delay and try again - # Note: sleep 1 didn't help with ": Permission denied" - sleep 2 - echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." - continue - fi - - set +e - instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ - "$TEST_NAME.jmap" \ - | sed ' - # strip leading whitespace; does nothing in JDK1.5.0 - s/^'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip field - s/'"${PATTERN_WS}"'.*// - '` - set -e - if [ -z "$instance_cnt" ]; then - echo "INFO: instance count is unexpectedly empty" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no sample was found." - echo "INFO: There is likely a problem with the sed filter." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." - echo "FAIL: cannot find the instance count value." >&2 - killApplication - exit 2 - fi - else - echo "INFO: instance_cnt = $instance_cnt" - - if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then - increasing_cnt=`expr $increasing_cnt + 1` - else - # actually decreasing or the same - decreasing_cnt=`expr $decreasing_cnt + 1` - - # For this particular WeakReference leak, the count was - # always observed to be increasing so if we get a decreasing - # or the same count, then the leak is fixed in the bits - # being tested. - echo "INFO: finishing early due to non-increasing instance count." - finished_early=true - killApplication - break - fi - prev_instance_cnt="$instance_cnt" - fi - - # delay between samples - sleep 5 - - loop_cnt=`expr $loop_cnt + 1` -done - -if [ $finished_early = false ]; then - stopApplication "$TEST_NAME.port" - waitForApplication -fi - -echo "INFO: $TEST_NAME has finished running." -echo "INFO: increasing_cnt = $increasing_cnt" -echo "INFO: decreasing_cnt = $decreasing_cnt" -if [ "$jmap_retry_cnt" -gt 0 ]; then - echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" -fi - -if [ "$loop_cnt" = 0 ]; then - echo "FAIL: jmap is unable to take any samples." >&2 - exit 2 -fi - -echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" -if [ "$decreasing_cnt" = 0 ]; then - echo "INFO: is always increasing." - echo "FAIL: This indicates that there is a memory leak." >&2 - exit 2 -fi - -echo "INFO: is not always increasing." -echo "PASS: This indicates that there is not a memory leak." -exit 0 diff --git a/jdk/test/java/util/logging/LoggerWeakRefLeak.java b/jdk/test/java/util/logging/LoggerWeakRefLeak.java deleted file mode 100644 index f93c7be6163..00000000000 --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010, 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.logging.*; - -public class LoggerWeakRefLeak extends SimpleApplication { - // The test driver script will allow this program to run until we - // reach DEFAULT_LOOP_TIME or a decrease in instance counts is - // observed. For these particular WeakReference leaks, the count - // was always observed to be increasing so if we get a decreasing - // count, then the leaks are fixed in the bits being tested. - // Two minutes has been enough time to observe a decrease in - // fixed bits on overloaded systems, but the test will likely - // finish more quickly. - public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - - // execute the LoggerWeakRefLeak app work - public void doMyAppWork(String[] args) throws Exception { - int loop_time = 0; - int max_loop_time = DEFAULT_LOOP_TIME; - - // args[0] is the port-file - if (args.length < 2) { - System.out.println("INFO: using default time of " - + max_loop_time + " seconds."); - } else { - try { - max_loop_time = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - throw new RuntimeException("Error: '" + args[1] - + "': is not a valid seconds value."); - } - } - - long count = 0; - int loggerCount = 0; - long now = 0; - long startTime = System.currentTimeMillis(); - - while (now < (startTime + (max_loop_time * 1000))) { - if ((count % 1000) == 0) { - // Print initial call count to let caller know that - // we're up and running and then periodically - System.out.println("INFO: call count = " + count); - } - - for (int i = 0; i < 100; i++) { - // This Logger call is leaking two different WeakReferences: - // - one in LogManager.LogNode - // - one in Logger.kids - java.util.logging.Logger.getLogger("logger-" + loggerCount); - count++; - if (++loggerCount >= 25000) { - // Limit the Logger namespace used by the test so - // the weak refs in LogManager.loggers that are - // being properly managed don't skew the counts - // by too much. - loggerCount = 0; - } - } - - try { - // delay for 1/10 of a second to avoid CPU saturation - Thread.sleep(100); - } catch (InterruptedException ie) { - // ignore any exceptions - } - - now = System.currentTimeMillis(); - } - - System.out.println("INFO: final loop count = " + count); - } - - public static void main(String[] args) throws Exception { - AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); - - SimpleApplication.setMyApp(myApp); - - SimpleApplication.main(args); - } -} diff --git a/jdk/test/java/util/logging/LoggerWeakRefLeak.sh b/jdk/test/java/util/logging/LoggerWeakRefLeak.sh deleted file mode 100644 index 25cc4aabc74..00000000000 --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6942989 -# @summary Check for WeakReference leak in Logger objects -# @author Daniel D. Daugherty -# -# @library ../../../sun/tools/common -# @build SimpleApplication ShutdownSimpleApplication -# @build LoggerWeakRefLeak -# @run shell/timeout=240 LoggerWeakRefLeak.sh - -# The timeout is: 2 minutes for infrastructure and 2 minutes for the test -# - -. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh -. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh - - -TEST_NAME="LoggerWeakRefLeak" -TARGET_CLASS="java\.lang\.ref\.WeakReference" - - -# MAIN begins here -# - -seconds= -if [ "$#" -gt 0 ]; then - seconds="$1" -fi - -# see if this version of jmap supports the '-histo:live' option -jmap_option="-histo:live" -set +e -"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 -status="$?" -set -e -if [ "$status" != 0 ]; then - # usage message doesn't show ':live' option - - if $isWindows; then - # If SA isn't present, then jmap gives a different usage message - # that doesn't show the ':live' option. However, that's a bug that - # is covered by 6971851 so we try using the option just to be sure. - # For some reason, this problem has only been seen on OpenJDK6 on - # Windows. Not sure why. - set +e - # Note: Don't copy this code to try probing process 0 on Linux; it - # will kill the process group in strange ways. - "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - # Usage message generated so flag the problem. - status=1 - else - # No usage message so clear the flag. - status=0 - fi - fi - - if [ "$status" != 0 ]; then - echo "WARNING: 'jmap $jmap_option' is not supported on this platform" - echo "WARNING: so this test cannot work reliably. Aborting!" - exit 0 - fi -fi - -# Start application and use TEST_NAME.port for coordination -startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds - -finished_early=false - -decreasing_cnt=0 -increasing_cnt=0 -loop_cnt=0 -prev_instance_cnt=0 - -MAX_JMAP_TRY_CNT=10 -jmap_retry_cnt=0 -loop_cnt_on_retry=0 - -while true; do - # see if the target process has finished its run and bail if it has - set +e - grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - break - fi - - # Output format for 'jmap -histo' in JDK1.5.0: - # - # <#bytes> <#instances> - # - # Output format for 'jmap -histo:live': - # - # : <#instances> <#bytes> - # - set +e - "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 - status="$?" - set -e - - if [ "$status" != 0 ]; then - echo "INFO: jmap exited with exit code = $status" - - # There are intermittent jmap failures; see 6498448. - # - # So far the following have been observed in a jmap call - # that was not in a race with target process termination: - # - # (Solaris specific, 2nd sample) - # : Unable to open door: target process not responding or HotSpot VM not loaded - # The -F option can be used when the target process is not responding - # - # (on Solaris so far) - # java.io.IOException - # - # (on Solaris so far, 1st sample) - # : Permission denied - # - sed 's/^/INFO: /' "$TEST_NAME.jmap" - - if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then - # loop count hasn't changed - jmap_retry_cnt=`expr $jmap_retry_cnt + 1` - else - # loop count has changed so remember it - jmap_retry_cnt=1 - loop_cnt_on_retry="$loop_cnt" - fi - - # This is '-ge' because we have the original attempt plus - # MAX_JMAP_TRY_CNT - 1 retries. - if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then - echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ - "without making any progress." - echo "FAIL: jmap is unable to take any samples." >&2 - killApplication - exit 2 - fi - - # short delay and try again - # Note: sleep 1 didn't help with ": Permission denied" - sleep 2 - echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." - continue - fi - - set +e - instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ - "$TEST_NAME.jmap" \ - | sed ' - # strip leading whitespace; does nothing in JDK1.5.0 - s/^'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip field - s/'"${PATTERN_WS}"'.*// - '` - set -e - if [ -z "$instance_cnt" ]; then - echo "INFO: instance count is unexpectedly empty" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no sample was found." - echo "INFO: There is likely a problem with the sed filter." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." - echo "FAIL: cannot find the instance count value." >&2 - killApplication - exit 2 - fi - else - echo "INFO: instance_cnt = $instance_cnt" - - if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then - increasing_cnt=`expr $increasing_cnt + 1` - else - # actually decreasing or the same - decreasing_cnt=`expr $decreasing_cnt + 1` - - # For these particular WeakReference leaks, the count was - # always observed to be increasing so if we get a decreasing - # or the same count, then the leaks are fixed in the bits - # being tested. - echo "INFO: finishing early due to non-increasing instance count." - finished_early=true - killApplication - break - fi - prev_instance_cnt="$instance_cnt" - fi - - # delay between samples - sleep 5 - - loop_cnt=`expr $loop_cnt + 1` -done - -if [ $finished_early = false ]; then - stopApplication "$TEST_NAME.port" - waitForApplication -fi - -echo "INFO: $TEST_NAME has finished running." -echo "INFO: increasing_cnt = $increasing_cnt" -echo "INFO: decreasing_cnt = $decreasing_cnt" -if [ "$jmap_retry_cnt" -gt 0 ]; then - echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" -fi - -if [ "$loop_cnt" = 0 ]; then - echo "FAIL: jmap is unable to take any samples." >&2 - exit 2 -fi - -echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" -if [ "$decreasing_cnt" = 0 ]; then - echo "INFO: is always increasing." - echo "FAIL: This indicates that there is a memory leak." >&2 - exit 2 -fi - -echo "INFO: is not always increasing." -echo "PASS: This indicates that there is not a memory leak." -exit 0 diff --git a/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java b/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java new file mode 100644 index 00000000000..3f6d403cba7 --- /dev/null +++ b/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static jdk.testlibrary.Asserts.assertGreaterThan; +import jdk.testlibrary.ProcessTools; + +import com.sun.tools.attach.AttachNotSupportedException; +import com.sun.tools.attach.VirtualMachine; + +import sun.tools.attach.HotSpotVirtualMachine; + +/* + * @test + * @bug 6942989 + * @summary Check for WeakReference leak in Logger and anonymous Logger objects + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main/othervm TestLoggerWeakRefLeak Logger + * @run main/othervm TestLoggerWeakRefLeak AnonymousLogger + */ +public class TestLoggerWeakRefLeak { + + private static final String TARGET_CLASS = "java.lang.ref.WeakReference"; + private static final int INSTANCE_COUNT = 100; + private static int loggerCount = 0; + + public static void main(String[] args) throws Exception { + if (args[0].equals("AnonymousLogger")) { + System.out.println("Test for WeakReference leak in AnonymousLogger object"); + testIfLeaking(TestLoggerWeakRefLeak::callAnonymousLogger); + } else { + System.out.println("Test for WeakReference leak in Logger object"); + testIfLeaking(TestLoggerWeakRefLeak::callLogger); + } + } + + /** + * For these particular WeakReference leaks, the count was always observed + * to be increasing so if decreasing or the same count is observed, + * then there is no leak. + */ + private static void testIfLeaking(Runnable callLogger) throws Exception { + long count = 0; + int instanceCount = 0; + int previousInstanceCount = 0; + int increasingCount = 0; + int decreasingCount = 0; + + while (true) { + callLogger.run(); + count += INSTANCE_COUNT; + + if ((count % 1000) == 0) { + System.out.println("call count = " + count); + + instanceCount = getInstanceCountFromHeapHisto(); + if (instanceCount > previousInstanceCount) { + increasingCount++; + } else { + decreasingCount++; + System.out.println("increasing count: " + increasingCount); + System.out.println("decreasing or the same count: " + decreasingCount); + System.out.println("Test passed: decreasing or the same instance count is observed"); + break; + } + previousInstanceCount = instanceCount; + } + + delayExecution(); + } + } + + /** + * This Logger call is leaking two different WeakReferences: + * - one in LogManager.LogNode + * - one in Logger.kids + */ + private static void callLogger() { + for (int i = 0; i < INSTANCE_COUNT; i++) { + java.util.logging.Logger.getLogger("logger-" + loggerCount); + if (++loggerCount >= 25000) { + // Limit the Logger namespace used by the test so the weak refs + // in LogManager.loggers that are being properly managed + // don't skew the counts by too much. + loggerCount = 0; + } + } + } + + /** + * This Logger call is leaking a WeakReference in Logger.kids + */ + private static void callAnonymousLogger() { + for (int i = 0; i < INSTANCE_COUNT; i++) { + java.util.logging.Logger.getAnonymousLogger(); + } + } + + /** + * 'vm.heapHisto("-live")' will request a full GC + */ + private static int getInstanceCountFromHeapHisto() throws AttachNotSupportedException, Exception { + int instanceCount = 0; + + HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine + .attach(Integer.toString(ProcessTools.getProcessId())); + try { + try (InputStream heapHistoStream = vm.heapHisto("-live"); + BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) { + String inputLine; + while ((inputLine = in.readLine()) != null) { + if (inputLine.contains(TARGET_CLASS)) { + instanceCount = Integer.parseInt(inputLine + .split("[ ]+")[2]); + System.out.println("instance count: " + instanceCount); + break; + } + } + } + } finally { + vm.detach(); + } + + assertGreaterThan(instanceCount, 0, "No instances of " + TARGET_CLASS + " are found"); + + return instanceCount; + } + + /** + * Delay for 1/10 of a second to avoid CPU saturation + */ + private static void delayExecution() { + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + // Ignore any exceptions + } + } + +} diff --git a/jdk/test/sun/tools/common/CommonTests.sh b/jdk/test/sun/tools/common/CommonTests.sh deleted file mode 100644 index ae0287a0c32..00000000000 --- a/jdk/test/sun/tools/common/CommonTests.sh +++ /dev/null @@ -1,314 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6964018 -# @summary Unit test for common tools infrastructure. -# -# @build SimpleApplication SleeperApplication ShutdownSimpleApplication -# @run shell CommonTests.sh - -. ${TESTSRC}/CommonSetup.sh -. ${TESTSRC}/ApplicationSetup.sh - -# hope for the best: -status=0 - - -# Test program path constants from CommonSetup.sh: -# -for name in JAVA JHAT JINFO JMAP JPS JSTACK; do - eval value=$`echo $name` - - echo "INFO: $name=$value" - if [ -x "$value" ]; then - echo "INFO: '$value' is executable." - else - echo "ERROR: '$value' is not executable." >&2 - status=1 - fi -done - - -# Display flag values from CommonSetup.sh: -# -for name in isCygwin isMKS isLinux isSolaris isUnknownOS isWindows; do - eval value=$`echo $name` - echo "INFO: flag $name=$value" -done - - -# Test OS constant from CommonSetup.sh: -# -if [ -z "$OS" ]; then - echo "ERROR: OS constant cannot be empty." >&2 - status=1 -fi - - -# Display the PATTERN_EOL value: -# -echo "INFO: PATTERN_EOL="`echo "$PATTERN_EOL" | od -c` - - -# Test PATTERN_EOL with 'grep' for a regular line. -# -TESTOUT="${TESTCLASSES}/testout.grep_reg_line_eol" -set +e -echo 'regular line' | grep "line${PATTERN_EOL}" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for regular line with grep." -else - echo "ERROR: PATTERN_EOL does not work for regular line with grep." >&2 - status=1 -fi - - -if $isWindows; then - # Test PATTERN_EOL with 'grep' for a CR line. - # - TESTOUT="${TESTCLASSES}/testout.grep_cr_line_eol" - set +e - echo 'CR line ' | grep "line${PATTERN_EOL}" > "$TESTOUT" - set -e - if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for CR line with grep." - else - echo "ERROR: PATTERN_EOL does not work for CR line with grep." >&2 - status=1 - fi -fi - - -# Test PATTERN_EOL with 'sed' for a regular line. -# -TESTOUT="${TESTCLASSES}/testout.sed_reg_line_eol" -echo 'regular line' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for regular line with sed." -else - echo "ERROR: PATTERN_EOL does not work for regular line with sed." >&2 - status=1 -fi - - -if $isWindows; then - # Test PATTERN_EOL with 'sed' for a CR line. - # - TESTOUT="${TESTCLASSES}/testout.sed_cr_line_eol" - echo 'CR line ' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" - if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for CR line with sed." - else - echo "ERROR: PATTERN_EOL does not work for CR line with sed." >&2 - status=1 - fi -fi - - -# Display the PATTERN_WS value: -# -echo "INFO: PATTERN_WS="`echo "$PATTERN_WS" | od -c` - - -# Test PATTERN_WS with 'grep' for a blank. -# -TESTOUT="${TESTCLASSES}/testout.grep_blank" -set +e -echo 'blank: ' | grep "$PATTERN_WS" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for blanks with grep." -else - echo "ERROR: PATTERN_WS does not work for blanks with grep." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'grep' for a tab. -# -TESTOUT="${TESTCLASSES}/testout.grep_tab" -set +e -echo 'tab: ' | grep "$PATTERN_WS" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for tabs with grep." -else - echo "ERROR: PATTERN_WS does not work for tabs with grep." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'sed' for a blank. -# -TESTOUT="${TESTCLASSES}/testout.sed_blank" -echo 'blank: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for blanks with sed." -else - echo "ERROR: PATTERN_WS does not work for blanks with sed." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'sed' for a tab. -# -TESTOUT="${TESTCLASSES}/testout.sed_tab" -echo 'tab: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for tabs with sed." -else - echo "ERROR: PATTERN_WS does not work for tabs with sed." >&2 - status=1 -fi - - -# Test startApplication and use PORTFILE for coordination -# The app sleeps for 30 seconds. -# -PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication SleeperApplication "${PORTFILE}" 30 - - -# Test appJavaPid in "ps" cmd output. -# -TESTOUT="${TESTCLASSES}/testout.ps_app" -set +e -if $isCygwin; then - # On Cygwin, appJavaPid is the Windows pid for the Java process - # and appOtherPid is the Cygwin pid for the Java process. - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -fi -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: begin appJavaPid=$appJavaPid in 'ps' cmd output:" - cat "$TESTOUT" - echo "INFO: end appJavaPid=$appJavaPid in 'ps' cmd output." -else - echo "ERROR: 'ps' cmd should show appJavaPid=$appJavaPid." >&2 - status=1 -fi - -if [ -n "$appOtherPid" ]; then - # Test appOtherPid in "ps" cmd output, if we have one. - # - TESTOUT="${TESTCLASSES}/testout.ps_other" - set +e - if $isCygwin; then - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appOtherPid}${PATTERN_WS}" > "$TESTOUT" - else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appOtherPid}${PATTERN_WS}" > "$TESTOUT" - fi - set -e - if [ -s "$TESTOUT" ]; then - echo "INFO: begin appOtherPid=$appOtherPid in 'ps' cmd output:" - cat "$TESTOUT" - echo "INFO: end appOtherPid=$appOtherPid in 'ps' cmd output." - else - echo "ERROR: 'ps' cmd should show appOtherPid=$appOtherPid." >&2 - status=1 - fi -fi - - -# Test stopApplication and PORTFILE for coordination -# -stopApplication "${PORTFILE}" - - -# Test application still running after stopApplication. -# -# stopApplication just lets the app know that it can stop, but the -# app might still be doing work. This test just demonstrates that -# fact and doesn't fail if the app is already done. -# -TESTOUT="${TESTCLASSES}/testout.after_stop" -set +e -if $isCygwin; then - # On Cygwin, appJavaPid is the Windows pid for the Java process - # and appOtherPid is the Cygwin pid for the Java process. - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -fi -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: it is okay for appJavaPid=$appJavaPid to still be running" \ - "after stopApplication() is called." - echo "INFO: begin 'after_stop' output:" - cat "$TESTOUT" - echo "INFO: end 'after_stop' output." -fi - - -# Test waitForApplication -# -# The app might already be gone so this function shouldn't generate -# a fatal error in either call. -# -waitForApplication - -if [ $isWindows = false ]; then - # Windows can recycle pids quickly so we can't use this test there - TESTOUT="${TESTCLASSES}/testout.after_kill" - set +e - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" - set -e - if [ -s "$TESTOUT" ]; then - echo "ERROR: 'ps' cmd should not show appJavaPid." >&2 - echo "ERROR: begin 'after_kill' output:" >&2 - cat "$TESTOUT" >&2 - echo "ERROR: end 'after_kill' output." >&2 - status=1 - else - echo "INFO: 'ps' cmd does not show appJavaPid after" \ - "waitForApplication() is called." - fi -fi - - -# Test killApplication -# -# The app is already be gone so this function shouldn't generate -# a fatal error. -# -killApplication - -exit $status From f36d8eb8f36bdd4e17388548a6b61758d67fae54 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Fri, 19 Dec 2014 18:33:55 +0100 Subject: [PATCH 24/72] 8067923: AIX: link libjvm.so with -bernotok to detect missing symbols at build time and suppress warning 1540-1639 Reviewed-by: goetz --- hotspot/make/aix/makefiles/ppc64.make | 4 +++- hotspot/make/aix/makefiles/xlc.make | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hotspot/make/aix/makefiles/ppc64.make b/hotspot/make/aix/makefiles/ppc64.make index 079d0764769..2636a4b9742 100644 --- a/hotspot/make/aix/makefiles/ppc64.make +++ b/hotspot/make/aix/makefiles/ppc64.make @@ -46,7 +46,9 @@ CFLAGS += -qsuppress=1540-0198 # - 1540-1090 (I) The destructor of "..." might not be called. # - 1500-010: (W) WARNING in ...: Infinite loop. Program may not stop. # There are several infinite loops in the vm, suppress. -CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010 +# - 1540-1639 (I) The behavior of long type bit fields has changed ... +# ... long type bit fields now default to long, not int. +CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010 -qsuppress=1540-1639 # Suppress # - 540-1088 (W) The exception specification is being ignored. diff --git a/hotspot/make/aix/makefiles/xlc.make b/hotspot/make/aix/makefiles/xlc.make index f281a08ea4f..b6525327528 100644 --- a/hotspot/make/aix/makefiles/xlc.make +++ b/hotspot/make/aix/makefiles/xlc.make @@ -124,7 +124,7 @@ STATIC_STDCXX = -Wl,-lC_r # MAPFLAG = -Xlinker --version-script=FILENAME # Build shared library -SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath +SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok #------------------------------------------------------------------------ # Debug flags From 52a48239508a01794a019e2a202f9db7e6cd2de5 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 23 Dec 2014 15:48:32 +0100 Subject: [PATCH 25/72] 8068018: Clean up friends of G1CollectedHeap Remove unnecessary friend class declaration in the G1CollectedHeap class. Reviewed-by: jwilhelm, jmasa --- .../vm/gc_implementation/g1/g1Allocator.cpp | 4 ++-- .../gc_implementation/g1/g1CollectedHeap.hpp | 18 ------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp index 45ab111b720..da75e61a8a7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp @@ -99,8 +99,8 @@ void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, Evacuat } if (ResizePLAB) { - _g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); - _g1h->_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); + _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(no_of_gc_workers); + _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(no_of_gc_workers); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 2d1921da897..4b4878e33b8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -186,32 +186,14 @@ class G1CollectedHeap : public SharedHeap { friend class SurvivorGCAllocRegion; friend class OldGCAllocRegion; friend class G1Allocator; - friend class G1DefaultAllocator; - friend class G1ResManAllocator; // Closures used in implementation. - template - friend class G1ParCopyClosure; - friend class G1IsAliveClosure; - friend class G1EvacuateFollowersClosure; friend class G1ParScanThreadState; - friend class G1ParScanClosureSuper; - friend class G1ParEvacuateFollowersClosure; friend class G1ParTask; friend class G1ParGCAllocator; - friend class G1DefaultParGCAllocator; - friend class G1FreeGarbageRegionClosure; - friend class RefineCardTableEntryClosure; friend class G1PrepareCompactClosure; - friend class RegionSorter; - friend class RegionResetter; - friend class CountRCClosure; - friend class EvacPopObjClosure; - friend class G1ParCleanupCTTask; - friend class G1FreeHumongousRegionClosure; // Other related classes. - friend class G1MarkSweep; friend class HeapRegionClaimer; // Testing classes. From 79439ff560ab4c0f8ff816a29c60ed333e10da94 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Mon, 22 Dec 2014 17:33:29 +0100 Subject: [PATCH 26/72] 8067947: Regression test for JDK-6522873 Added a regression test that will fail if we allow extra characters after flag names Reviewed-by: ctornqvi, tschatzl --- .../CommandLine/TestNullTerminatedFlags.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java diff --git a/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java new file mode 100644 index 00000000000..f439065b670 --- /dev/null +++ b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test TestNullTerminatedFlags + * @bug 6522873 + * @summary Test that the VM don't allow random junk characters at the end of valid command line flags. + * @library /testlibrary + * @run driver TestNullTerminatedFlags + */ +public class TestNullTerminatedFlags { + public static String[] options = { + "-Xnoclassgc", + "-Xconcgc", + "-Xnoconcgc", + "-Xbatch", + "-green", + "-native", + "-Xsqnopause", + "-Xrs", + "-Xusealtsigs", + "-Xoptimize", + "-Xprof", + "-Xconcurrentio", + "-Xinternalversion", + "-Xprintflags", + "-Xint", + "-Xmixed", + "-Xcomp", + "-Xshare:dump", + "-Xshare:on", + "-Xshare:auto", + "-Xshare:off", + "-Xdebug", + "-Xnoagent", + "-Xboundthreads" + }; + + public static void main(String args[]) throws Exception{ + for (String option : options) { + String testOption = option + "junk"; + ProcessBuilder pb = + ProcessTools.createJavaProcessBuilder(testOption, "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Unrecognized option: " + testOption) + .shouldHaveExitValue(1); + } + } +} + From 53664dc9769fe0066ba7ecf3f00af3714ee93e42 Mon Sep 17 00:00:00 2001 From: Alexander Kulyakthin Date: Sat, 27 Dec 2014 07:09:32 -0800 Subject: [PATCH 27/72] 8068242: Quarantine the test IsModifiableClassAgent.java Quarantine the test Reviewed-by: hseigel, jbachorik, dsamersoff --- jdk/test/java/lang/instrument/IsModifiableClassAgent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/java/lang/instrument/IsModifiableClassAgent.java b/jdk/test/java/lang/instrument/IsModifiableClassAgent.java index 843672d3993..31329dfd3a1 100644 --- a/jdk/test/java/lang/instrument/IsModifiableClassAgent.java +++ b/jdk/test/java/lang/instrument/IsModifiableClassAgent.java @@ -23,6 +23,7 @@ /** * @test + * @ignore JDK-8068162 * @bug 6331574 * @summary test isModifiableClass * @author Robert Field, Sun Microsystems From f096def67ac58700271e3dc5643d52124cbd44b0 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Mon, 29 Dec 2014 19:07:09 +0100 Subject: [PATCH 28/72] 8068233: java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java is still in exclude list Reviewed-by: chegar, sspitsyn --- jdk/test/ProblemList.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 8648fbd96eb..9eecc4d5d1b 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -138,9 +138,6 @@ java/lang/instrument/RetransformBigClass.sh generic-all # 8058492 java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all -# 8058506 -java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java generic-all - ############################################################################ # jdk_jmx From 0cb9e3ec88f9d98a64e88124a284d907493c6323 Mon Sep 17 00:00:00 2001 From: Filipp Zhinkin Date: Tue, 30 Dec 2014 11:05:01 +0300 Subject: [PATCH 29/72] 8068272: Extend WhiteBox API with methods that check monitor state and force safepoint Reviewed-by: kvn, iignatyev --- test/lib/sun/hotspot/WhiteBox.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/lib/sun/hotspot/WhiteBox.java b/test/lib/sun/hotspot/WhiteBox.java index 4da988a8fd5..b19845392ff 100644 --- a/test/lib/sun/hotspot/WhiteBox.java +++ b/test/lib/sun/hotspot/WhiteBox.java @@ -84,6 +84,8 @@ public class WhiteBox { return isClassAlive0(name.replace('.', '/')); } private native boolean isClassAlive0(String name); + public native boolean isMonitorInflated(Object obj); + public native void forceSafepoint(); // JVMTI public native void addToBootstrapClassLoaderSearch(String segment); From 5b8ee4c10250949deff2146589d76dc4fb6f4c88 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Tue, 30 Dec 2014 12:59:20 -0500 Subject: [PATCH 30/72] 8064335: Null pointer dereference in hotspot/src/share/vm/classfile/verifier.cpp Use correct CHECK macro in call to load_class() Reviewed-by: coleenp, lfoltan, gziemski --- hotspot/src/share/vm/classfile/verifier.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index d5094ae55be..679d70de021 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -2477,8 +2477,7 @@ void ClassVerifier::verify_invoke_init( // of the current class. VerificationType objectref_type = new_class_type; if (name_in_supers(ref_class_type.name(), current_class())) { - Klass* ref_klass = load_class( - ref_class_type.name(), CHECK_VERIFY(this)); + Klass* ref_klass = load_class(ref_class_type.name(), CHECK); Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), cp->signature_ref_at(bcs->get_index_u2()), From 1c18aef92c52c4e3ef62daa44741394e5dfc9619 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 5 Jan 2015 12:07:37 -0500 Subject: [PATCH 31/72] 8064457: Introduce compressed oops mode disjoint base and improve compressed heap handling Introduce compressed oops mode disjoint base and improve compressed heap handling. Reviewed-by: kvn, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 8 +- hotspot/src/share/vm/memory/universe.cpp | 197 ++------- hotspot/src/share/vm/memory/universe.hpp | 33 +- hotspot/src/share/vm/opto/matcher.hpp | 9 +- hotspot/src/share/vm/prims/whitebox.cpp | 8 +- hotspot/src/share/vm/runtime/arguments.cpp | 16 +- hotspot/src/share/vm/runtime/arguments.hpp | 3 +- hotspot/src/share/vm/runtime/globals.hpp | 7 +- hotspot/src/share/vm/runtime/virtualspace.cpp | 383 +++++++++++++++--- hotspot/src/share/vm/runtime/virtualspace.hpp | 35 +- .../share/vm/utilities/globalDefinitions.hpp | 19 +- .../vm/utilities/globalDefinitions_xlc.hpp | 32 +- .../CompressedOops/UseCompressedOops.java | 76 +++- 13 files changed, 530 insertions(+), 296 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 7448b3e62d7..de7ea1abee1 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -422,7 +422,7 @@ VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs( bool large_pages = false; // No large pages when dumping the CDS archive. char* shared_base = (char*)align_ptr_up((char*)SharedBaseAddress, Metaspace::reserve_alignment()); - _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages, shared_base, 0); + _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages, shared_base); if (_rs.is_reserved()) { assert(shared_base == 0 || _rs.base() == shared_base, "should match"); } else { @@ -3025,7 +3025,7 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a ReservedSpace metaspace_rs = ReservedSpace(compressed_class_space_size(), _reserve_alignment, large_pages, - requested_addr, 0); + requested_addr); if (!metaspace_rs.is_reserved()) { #if INCLUDE_CDS if (UseSharedSpaces) { @@ -3039,7 +3039,7 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a can_use_cds_with_metaspace_addr(addr + increment, cds_base)) { addr = addr + increment; metaspace_rs = ReservedSpace(compressed_class_space_size(), - _reserve_alignment, large_pages, addr, 0); + _reserve_alignment, large_pages, addr); } } #endif diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 865f6b0c23c..fe33e7a156f 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -694,103 +694,6 @@ jint universe_init() { // NarrowOopHeapBaseMin + heap_size < 32Gb // HeapBased - Use compressed oops with heap base + encoding. -// 4Gb -static const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); -// 32Gb -// OopEncodingHeapMax == UnscaledOopHeapMax << LogMinObjAlignmentInBytes; - -char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) { - assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be"); - assert(is_size_aligned((size_t)UnscaledOopHeapMax, alignment), "Must be"); - assert(is_size_aligned(heap_size, alignment), "Must be"); - - uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment); - - size_t base = 0; -#ifdef _LP64 - if (UseCompressedOops) { - assert(mode == UnscaledNarrowOop || - mode == ZeroBasedNarrowOop || - mode == HeapBasedNarrowOop, "mode is invalid"); - const size_t total_size = heap_size + heap_base_min_address_aligned; - // Return specified base for the first request. - if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { - base = heap_base_min_address_aligned; - - // If the total size is small enough to allow UnscaledNarrowOop then - // just use UnscaledNarrowOop. - } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) { - if ((total_size <= UnscaledOopHeapMax) && (mode == UnscaledNarrowOop) && - (Universe::narrow_oop_shift() == 0)) { - // Use 32-bits oops without encoding and - // place heap's top on the 4Gb boundary - base = (UnscaledOopHeapMax - heap_size); - } else { - // Can't reserve with NarrowOopShift == 0 - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - - if (mode == UnscaledNarrowOop || - mode == ZeroBasedNarrowOop && total_size <= UnscaledOopHeapMax) { - - // Use zero based compressed oops with encoding and - // place heap's top on the 32Gb boundary in case - // total_size > 4Gb or failed to reserve below 4Gb. - uint64_t heap_top = OopEncodingHeapMax; - - // For small heaps, save some space for compressed class pointer - // space so it can be decoded with no base. - if (UseCompressedClassPointers && !UseSharedSpaces && - OopEncodingHeapMax <= 32*G) { - - uint64_t class_space = align_size_up(CompressedClassSpaceSize, alignment); - assert(is_size_aligned((size_t)OopEncodingHeapMax-class_space, - alignment), "difference must be aligned too"); - uint64_t new_top = OopEncodingHeapMax-class_space; - - if (total_size <= new_top) { - heap_top = new_top; - } - } - - // Align base to the adjusted top of the heap - base = heap_top - heap_size; - } - } - } else { - // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or - // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb. - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - } - - // Set narrow_oop_base and narrow_oop_use_implicit_null_checks - // used in ReservedHeapSpace() constructors. - // The final values will be set in initialize_heap() below. - if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) { - // Use zero based compressed oops - Universe::set_narrow_oop_base(NULL); - // Don't need guard page for implicit checks in indexed - // addressing mode with zero based Compressed Oops. - Universe::set_narrow_oop_use_implicit_null_checks(true); - } else { - // Set to a non-NULL value so the ReservedSpace ctor computes - // the correct no-access prefix. - // The final value will be set in initialize_heap() below. - Universe::set_narrow_oop_base((address)UnscaledOopHeapMax); -#if defined(_WIN64) || defined(AIX) - if (UseLargePages) { - // Cannot allocate guard pages for implicit checks in indexed - // addressing mode when large pages are specified on windows. - Universe::set_narrow_oop_use_implicit_null_checks(false); - } -#endif // _WIN64 - } - } -#endif - - assert(is_ptr_aligned((char*)base, alignment), "Must be"); - return (char*)base; // also return NULL (don't care) for 32-bit VM -} - jint Universe::initialize_heap() { if (UseParallelGC) { @@ -844,30 +747,13 @@ jint Universe::initialize_heap() { // See needs_explicit_null_check. // Only set the heap base for compressed oops because it indicates // compressed oops for pstack code. - if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) { - // Can't reserve heap below 32Gb. - // keep the Universe::narrow_oop_base() set in Universe::reserve_heap() + if ((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) { + // Didn't reserve heap below 4Gb. Must shift. Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); -#ifdef AIX - // There is no protected page before the heap. This assures all oops - // are decoded so that NULL is preserved, so this page will not be accessed. - Universe::set_narrow_oop_use_implicit_null_checks(false); -#endif - } else { + } + if ((uint64_t)Universe::heap()->reserved_region().end() <= OopEncodingHeapMax) { + // Did reserve heap below 32Gb. Can use base == 0; Universe::set_narrow_oop_base(0); -#ifdef _WIN64 - if (!Universe::narrow_oop_use_implicit_null_checks()) { - // Don't need guard page for implicit checks in indexed addressing - // mode with zero based Compressed Oops. - Universe::set_narrow_oop_use_implicit_null_checks(true); - } -#endif // _WIN64 - if((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) { - // Can't reserve heap below 4Gb. - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - } else { - Universe::set_narrow_oop_shift(0); - } } Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); @@ -875,6 +761,11 @@ jint Universe::initialize_heap() { if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { Universe::print_compressed_oops_mode(); } + + // Tell tests in which mode we run. + Arguments::PropertyList_add(new SystemProperty("java.vm.compressedOopsMode", + narrow_oop_mode_to_string(narrow_oop_mode()), + false)); } // Universe::narrow_oop_base() is one page below the heap. assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - @@ -903,22 +794,27 @@ void Universe::print_compressed_oops_mode() { tty->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); if (Universe::narrow_oop_base() != 0) { - tty->print(":" PTR_FORMAT, Universe::narrow_oop_base()); + tty->print(": " PTR_FORMAT, Universe::narrow_oop_base()); } if (Universe::narrow_oop_shift() != 0) { tty->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); } + if (!Universe::narrow_oop_use_implicit_null_checks()) { + tty->print(", no protected page in front of the heap"); + } + tty->cr(); tty->cr(); } -// Reserve the Java heap, which is now the same for all GCs. ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { + assert(alignment <= Arguments::conservative_max_heap_alignment(), err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT, alignment, Arguments::conservative_max_heap_alignment())); + size_t total_reserved = align_size_up(heap_size, alignment); assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), "heap size is too big for compressed oops"); @@ -928,46 +824,31 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { || UseParallelGC || use_large_pages, "Wrong alignment to use large pages"); - char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop); + // Now create the space. + ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages); - ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, addr); + if (total_rs.is_reserved()) { + assert((total_reserved == total_rs.size()) && ((uintptr_t)total_rs.base() % alignment == 0), + "must be exactly of required size and alignment"); + // We are good. - if (UseCompressedOops) { - if (addr != NULL && !total_rs.is_reserved()) { - // Failed to reserve at specified address - the requested memory - // region is taken already, for example, by 'java' launcher. - // Try again to reserver heap higher. - addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::ZeroBasedNarrowOop); - - ReservedHeapSpace total_rs0(total_reserved, alignment, - use_large_pages, addr); - - if (addr != NULL && !total_rs0.is_reserved()) { - // Failed to reserve at specified address again - give up. - addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::HeapBasedNarrowOop); - assert(addr == NULL, ""); - - ReservedHeapSpace total_rs1(total_reserved, alignment, - use_large_pages, addr); - total_rs = total_rs1; - } else { - total_rs = total_rs0; - } + if (UseCompressedOops) { + // Universe::initialize_heap() will reset this to NULL if unscaled + // or zero-based narrow oops are actually used. + // Else heap start and base MUST differ, so that NULL can be encoded nonambigous. + Universe::set_narrow_oop_base((address)total_rs.compressed_oop_base()); } - } - if (!total_rs.is_reserved()) { - vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K)); return total_rs; } - if (UseCompressedOops) { - // Universe::initialize_heap() will reset this to NULL if unscaled - // or zero-based narrow oops are actually used. - address base = (address)(total_rs.base() - os::vm_page_size()); - Universe::set_narrow_oop_base(base); - } - return total_rs; + vm_exit_during_initialization( + err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", + total_reserved/K)); + + // satisfy compiler + ShouldNotReachHere(); + return ReservedHeapSpace(0, 0, false); } @@ -985,6 +866,8 @@ const char* Universe::narrow_oop_mode_to_string(Universe::NARROW_OOP_MODE mode) return "32-bit"; case ZeroBasedNarrowOop: return "Zero based"; + case DisjointBaseNarrowOop: + return "Non-zero disjoint base"; case HeapBasedNarrowOop: return "Non-zero based"; } @@ -995,6 +878,10 @@ const char* Universe::narrow_oop_mode_to_string(Universe::NARROW_OOP_MODE mode) Universe::NARROW_OOP_MODE Universe::narrow_oop_mode() { + if (narrow_oop_base_disjoint()) { + return DisjointBaseNarrowOop; + } + if (narrow_oop_base() != 0) { return HeapBasedNarrowOop; } diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index 52334d0dbce..2235cd1c876 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,8 +102,8 @@ class Universe: AllStatic { friend class MarkSweep; friend class oopDesc; friend class ClassLoader; - friend class Arguments; friend class SystemDictionary; + friend class ReservedHeapSpace; friend class VMStructs; friend class VM_PopulateDumpSharedSpace; friend class Metaspace; @@ -351,17 +351,40 @@ class Universe: AllStatic { // NarrowOopHeapBaseMin + heap_size < 4Gb // 1 - Use zero based compressed oops with encoding when // NarrowOopHeapBaseMin + heap_size < 32Gb - // 2 - Use compressed oops with heap base + encoding. + // 2 - Use compressed oops with disjoint heap base if + // base is 32G-aligned and base > 0. This allows certain + // optimizations in encoding/decoding. + // Disjoint: Bits used in base are disjoint from bits used + // for oops ==> oop = (cOop << 3) | base. One can disjoint + // the bits of an oop into base and compressed oop. + // 3 - Use compressed oops with heap base + encoding. enum NARROW_OOP_MODE { UnscaledNarrowOop = 0, ZeroBasedNarrowOop = 1, - HeapBasedNarrowOop = 2 + DisjointBaseNarrowOop = 2, + HeapBasedNarrowOop = 3, + AnyNarrowOopMode = 4 }; static NARROW_OOP_MODE narrow_oop_mode(); static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode); static char* preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode); static char* preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode); - static address narrow_oop_base() { return _narrow_oop._base; } + static address narrow_oop_base() { return _narrow_oop._base; } + // Test whether bits of addr and possible offsets into the heap overlap. + static bool is_disjoint_heap_base_address(address addr) { + return (((uint64_t)(intptr_t)addr) & + (((uint64_t)UCONST64(0xFFFFffffFFFFffff)) >> (32-LogMinObjAlignmentInBytes))) == 0; + } + // Check for disjoint base compressed oops. + static bool narrow_oop_base_disjoint() { + return _narrow_oop._base != NULL && is_disjoint_heap_base_address(_narrow_oop._base); + } + // Check for real heapbased compressed oops. + // We must subtract the base as the bits overlap. + // If we negate above function, we also get unscaled and zerobased. + static bool narrow_oop_base_overlaps() { + return _narrow_oop._base != NULL && !is_disjoint_heap_base_address(_narrow_oop._base); + } static bool is_narrow_oop_base(void* addr) { return (narrow_oop_base() == (address)addr); } static int narrow_oop_shift() { return _narrow_oop._shift; } static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; } diff --git a/hotspot/src/share/vm/opto/matcher.hpp b/hotspot/src/share/vm/opto/matcher.hpp index 66d4a0adab9..d88771aeda6 100644 --- a/hotspot/src/share/vm/opto/matcher.hpp +++ b/hotspot/src/share/vm/opto/matcher.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -433,6 +433,13 @@ public: // NullCheck oop_reg // inline static bool gen_narrow_oop_implicit_null_checks() { + // Advice matcher to perform null checks on the narrow oop side. + // Implicit checks are not possible on the uncompressed oop side anyway + // (at least not for read accesses). + // Performs significantly better (especially on Power 6). + if (!os::zero_page_read_protected()) { + return true; + } return Universe::narrow_oop_use_implicit_null_checks() && (narrow_oop_use_complex_address() || Universe::narrow_oop_base() != NULL); diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index afde0ae63e1..bb5be7bff3f 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,11 +176,11 @@ WB_END WB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o)) size_t granularity = os::vm_allocation_granularity(); - ReservedHeapSpace rhs(100 * granularity, granularity, false, NULL); + ReservedHeapSpace rhs(100 * granularity, granularity, false); VirtualSpace vs; vs.initialize(rhs, 50 * granularity); - //Check if constraints are complied + // Check if constraints are complied if (!( UseCompressedOops && rhs.base() != NULL && Universe::narrow_oop_base() != NULL && Universe::narrow_oop_use_implicit_null_checks() )) { @@ -203,7 +203,7 @@ WB_END static jint wb_stress_virtual_space_resize(size_t reserved_space_size, size_t magnitude, size_t iterations) { size_t granularity = os::vm_allocation_granularity(); - ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false, NULL); + ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false); VirtualSpace vs; if (!vs.initialize(rhs, 0)) { tty->print_cr("Failed to initialize VirtualSpace. Can't proceed."); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 57ec22b81c3..66500908d85 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1522,15 +1522,6 @@ void Arguments::set_use_compressed_oops() { FLAG_SET_ERGO(bool, UseCompressedOops, true); } #endif -#ifdef _WIN64 - if (UseLargePages && UseCompressedOops) { - // Cannot allocate guard pages for implicit checks in indexed addressing - // mode, when large pages are specified on windows. - // This flag could be switched ON if narrow oop base address is set to 0, - // see code in Universe::initialize_heap(). - Universe::set_narrow_oop_use_implicit_null_checks(false); - } -#endif // _WIN64 } else { if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { warning("Max heap size too large for Compressed Oops"); @@ -2416,6 +2407,7 @@ bool Arguments::check_vm_args_consistency() { #ifdef COMPILER1 status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize"); #endif + status = status && verify_min_value(HeapSearchSteps, 1, "HeapSearchSteps"); if (PrintNMTStatistics) { #if INCLUDE_NMT @@ -4102,6 +4094,10 @@ void Arguments::PropertyList_add(SystemProperty** plist, const char* k, char* v) PropertyList_add(plist, new_p); } +void Arguments::PropertyList_add(SystemProperty *element) { + PropertyList_add(&_system_properties, element); +} + // This add maintains unique property key in the list. void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, char* v, jboolean append) { if (plist == NULL) diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 9601aba690b..a0edd81f2e6 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -572,6 +572,7 @@ class Arguments : AllStatic { static void init_version_specific_system_properties(); // Property List manipulation + static void PropertyList_add(SystemProperty *element); static void PropertyList_add(SystemProperty** plist, SystemProperty *element); static void PropertyList_add(SystemProperty** plist, const char* k, char* v); static void PropertyList_unique_add(SystemProperty** plist, const char* k, char* v) { diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index cbd024e66bf..7e29670fb18 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -531,6 +531,11 @@ class CommandLineFlags { product_pd(uintx, HeapBaseMinAddress, \ "OS specific low limit for heap base address") \ \ + product(uintx, HeapSearchSteps, 3 PPC64_ONLY(+17), \ + "Heap allocation steps through preferred address regions to find" \ + " where it can allocate the heap. Number of steps to take per " \ + "region.") \ + \ diagnostic(bool, PrintCompressedOopsMode, false, \ "Print compressed oops base address and encoding mode") \ \ diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 1a78a53c176..b659ec5eb06 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,21 +43,19 @@ ReservedSpace::ReservedSpace(size_t size) { // Don't force the alignment to be large page aligned, // since that will waste memory. size_t alignment = os::vm_allocation_granularity(); - initialize(size, alignment, large_pages, NULL, 0, false); + initialize(size, alignment, large_pages, NULL, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address, - const size_t noaccess_prefix) { - initialize(size+noaccess_prefix, alignment, large, requested_address, - noaccess_prefix, false); + char* requested_address) { + initialize(size, alignment, large, requested_address, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, bool executable) { - initialize(size, alignment, large, NULL, 0, executable); + initialize(size, alignment, large, NULL, executable); } // Helper method. @@ -91,7 +89,6 @@ static bool failed_to_reserve_as_requested(char* base, char* requested_address, void ReservedSpace::initialize(size_t size, size_t alignment, bool large, char* requested_address, - const size_t noaccess_prefix, bool executable) { const size_t granularity = os::vm_allocation_granularity(); assert((size & (granularity - 1)) == 0, @@ -103,10 +100,6 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large, alignment = MAX2(alignment, (size_t)os::vm_page_size()); - // Assert that if noaccess_prefix is used, it is the same as alignment. - assert(noaccess_prefix == 0 || - noaccess_prefix == alignment, "noaccess prefix wrong"); - _base = NULL; _size = 0; _special = false; @@ -122,11 +115,6 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large, bool special = large && !os::can_commit_large_page_memory(); char* base = NULL; - if (requested_address != 0) { - requested_address -= noaccess_prefix; // adjust requested address - assert(requested_address != NULL, "huge noaccess prefix?"); - } - if (special) { base = os::reserve_memory_special(size, alignment, requested_address, executable); @@ -176,7 +164,7 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large, if (base == NULL) return; // Check alignment constraints - if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) { + if ((((size_t)base) & (alignment - 1)) != 0) { // Base not aligned, retry if (!os::release_memory(base, size)) fatal("os::release_memory failed"); // Make sure that size is aligned @@ -197,16 +185,6 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large, _base = base; _size = size; _alignment = alignment; - _noaccess_prefix = noaccess_prefix; - - // Assert that if noaccess_prefix is used, it is the same as alignment. - assert(noaccess_prefix == 0 || - noaccess_prefix == _alignment, "noaccess prefix wrong"); - - assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, - "area must be distinguishable from marks for mark-sweep"); - assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], - "area must be distinguishable from marks for mark-sweep"); } @@ -276,54 +254,336 @@ void ReservedSpace::release() { _base = NULL; _size = 0; _noaccess_prefix = 0; + _alignment = 0; _special = false; _executable = false; } } -void ReservedSpace::protect_noaccess_prefix(const size_t size) { - assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL && - (Universe::narrow_oop_base() != NULL) && - Universe::narrow_oop_use_implicit_null_checks()), - "noaccess_prefix should be used only with non zero based compressed oops"); +static size_t noaccess_prefix_size(size_t alignment) { + return lcm(os::vm_page_size(), alignment); +} - // If there is no noaccess prefix, return. - if (_noaccess_prefix == 0) return; +void ReservedHeapSpace::establish_noaccess_prefix() { + assert(_alignment >= (size_t)os::vm_page_size(), "must be at least page size big"); + _noaccess_prefix = noaccess_prefix_size(_alignment); - assert(_noaccess_prefix >= (size_t)os::vm_page_size(), - "must be at least page size big"); - - // Protect memory at the base of the allocated region. - // If special, the page was committed (only matters on windows) - if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, - _special)) { - fatal("cannot protect protection page"); - } - if (PrintCompressedOopsMode) { - tty->cr(); - tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); + if (base() && base() + _size > (char *)OopEncodingHeapMax) { + if (true + WIN64_ONLY(&& !UseLargePages) + AIX_ONLY(&& os::vm_page_size() != SIZE_64K)) { + // Protect memory at the base of the allocated region. + // If special, the page was committed (only matters on windows) + if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) { + fatal("cannot protect protection page"); + } + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Protected page at the reserved heap base: " + PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); + } + assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?"); + } else { + Universe::set_narrow_oop_use_implicit_null_checks(false); + } } _base += _noaccess_prefix; _size -= _noaccess_prefix; - assert((size == _size) && ((uintptr_t)_base % _alignment == 0), - "must be exactly of required size and alignment"); + assert(((uintptr_t)_base % _alignment == 0), "must be exactly of required alignment"); } -ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, - bool large, char* requested_address) : - ReservedSpace(size, alignment, large, - requested_address, - (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && - Universe::narrow_oop_use_implicit_null_checks()) ? - lcm(os::vm_page_size(), alignment) : 0) { +// Tries to allocate memory of size 'size' at address requested_address with alignment 'alignment'. +// Does not check whether the reserved memory actually is at requested_address, as the memory returned +// might still fulfill the wishes of the caller. +// Assures the memory is aligned to 'alignment'. +// NOTE: If ReservedHeapSpace already points to some reserved memory this is freed, first. +void ReservedHeapSpace::try_reserve_heap(size_t size, + size_t alignment, + bool large, + char* requested_address) { + if (_base != NULL) { + // We tried before, but we didn't like the address delivered. + release(); + } + + // If OS doesn't support demand paging for large page memory, we need + // to use reserve_memory_special() to reserve and pin the entire region. + bool special = large && !os::can_commit_large_page_memory(); + char* base = NULL; + + if (PrintCompressedOopsMode && Verbose) { + tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " PTR_FORMAT ".\n", + requested_address, (address)size); + } + + if (special) { + base = os::reserve_memory_special(size, alignment, requested_address, false); + + if (base != NULL) { + // Check alignment constraints. + assert((uintptr_t) base % alignment == 0, + err_msg("Large pages returned a non-aligned address, base: " + PTR_FORMAT " alignment: " PTR_FORMAT, + base, (void*)(uintptr_t)alignment)); + _special = true; + } + } + + if (base == NULL) { + // Failed; try to reserve regular memory below + if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || + !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserve regular memory without large pages."); + } + } + + // Optimistically assume that the OSes returns an aligned base pointer. + // When reserving a large address range, most OSes seem to align to at + // least 64K. + + // If the memory was requested at a particular address, use + // os::attempt_reserve_memory_at() to avoid over mapping something + // important. If available space is not detected, return NULL. + + if (requested_address != 0) { + base = os::attempt_reserve_memory_at(size, requested_address); + } else { + base = os::reserve_memory(size, NULL, alignment); + } + } + if (base == NULL) { return; } + + // Done + _base = base; + _size = size; + _alignment = alignment; + + // Check alignment constraints + if ((((size_t)base) & (alignment - 1)) != 0) { + // Base not aligned, retry. + release(); + } +} + +void ReservedHeapSpace::try_reserve_range(char *highest_start, + char *lowest_start, + size_t attach_point_alignment, + char *aligned_heap_base_min_address, + char *upper_bound, + size_t size, + size_t alignment, + bool large) { + const size_t attach_range = highest_start - lowest_start; + // Cap num_attempts at possible number. + // At least one is possible even for 0 sized attach range. + const uint64_t num_attempts_possible = (attach_range / attach_point_alignment) + 1; + const uint64_t num_attempts_to_try = MIN2((uint64_t)HeapSearchSteps, num_attempts_possible); + + const size_t stepsize = (attach_range == 0) ? // Only one try. + (size_t) highest_start : align_size_up(attach_range / num_attempts_to_try, attach_point_alignment); + + // Try attach points from top to bottom. + char* attach_point = highest_start; + while (attach_point >= lowest_start && + attach_point <= highest_start && // Avoid wrap around. + ((_base == NULL) || + (_base < aligned_heap_base_min_address || _base + size > upper_bound))) { + try_reserve_heap(size, alignment, large, attach_point); + attach_point -= stepsize; + } +} + +#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) +#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) +#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) + +// Helper for heap allocation. Returns an array with addresses +// (OS-specific) which are suited for disjoint base mode. Array is +// NULL terminated. +static char** get_attach_addresses_for_disjoint_mode() { + static uint64_t addresses[] = { + 2 * SIZE_32G, + 3 * SIZE_32G, + 4 * SIZE_32G, + 8 * SIZE_32G, + 10 * SIZE_32G, + 1 * SIZE_64K * SIZE_32G, + 2 * SIZE_64K * SIZE_32G, + 3 * SIZE_64K * SIZE_32G, + 4 * SIZE_64K * SIZE_32G, + 16 * SIZE_64K * SIZE_32G, + 32 * SIZE_64K * SIZE_32G, + 34 * SIZE_64K * SIZE_32G, + 0 + }; + + // Sort out addresses smaller than HeapBaseMinAddress. This assumes + // the array is sorted. + uint i = 0; + while (addresses[i] != 0 && + (addresses[i] < OopEncodingHeapMax || addresses[i] < HeapBaseMinAddress)) { + i++; + } + uint start = i; + + // Avoid more steps than requested. + i = 0; + while (addresses[start+i] != 0) { + if (i == HeapSearchSteps) { + addresses[start+i] = 0; + break; + } + i++; + } + + return (char**) &addresses[start]; +} + +void ReservedHeapSpace::initialize_compressed_heap(const size_t size, size_t alignment, bool large) { + guarantee(size + noaccess_prefix_size(alignment) <= OopEncodingHeapMax, + "can not allocate compressed oop heap for this size"); + guarantee(alignment == MAX2(alignment, (size_t)os::vm_page_size()), "alignment too small"); + assert(HeapBaseMinAddress > 0, "sanity"); + + const size_t granularity = os::vm_allocation_granularity(); + assert((size & (granularity - 1)) == 0, + "size not aligned to os::vm_allocation_granularity()"); + assert((alignment & (granularity - 1)) == 0, + "alignment not aligned to os::vm_allocation_granularity()"); + assert(alignment == 0 || is_power_of_2((intptr_t)alignment), + "not a power of 2"); + + // The necessary attach point alignment for generated wish addresses. + // This is needed to increase the chance of attaching for mmap and shmat. + const size_t os_attach_point_alignment = + AIX_ONLY(SIZE_256M) // Known shm boundary alignment. + NOT_AIX(os::vm_allocation_granularity()); + const size_t attach_point_alignment = lcm(alignment, os_attach_point_alignment); + + char *aligned_heap_base_min_address = (char *)align_ptr_up((void *)HeapBaseMinAddress, alignment); + size_t noaccess_prefix = ((aligned_heap_base_min_address + size) > (char*)OopEncodingHeapMax) ? + noaccess_prefix_size(alignment) : 0; + + // Attempt to alloc at user-given address. + if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) { + try_reserve_heap(size + noaccess_prefix, alignment, large, aligned_heap_base_min_address); + if (_base != aligned_heap_base_min_address) { // Enforce this exact address. + release(); + } + } + + // Keep heap at HeapBaseMinAddress. + if (_base == NULL) { + + // Try to allocate the heap at addresses that allow efficient oop compression. + // Different schemes are tried, in order of decreasing optimization potential. + // + // For this, try_reserve_heap() is called with the desired heap base addresses. + // A call into the os layer to allocate at a given address can return memory + // at a different address than requested. Still, this might be memory at a useful + // address. try_reserve_heap() always returns this allocated memory, as only here + // the criteria for a good heap are checked. + + // Attempt to allocate so that we can run without base and scale (32-Bit unscaled compressed oops). + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= (char *)UnscaledOopHeapMax) { + + // Calc address range within we try to attach (range of possible start addresses). + char* const highest_start = (char *)align_ptr_down((char *)UnscaledOopHeapMax - size, attach_point_alignment); + char* const lowest_start = (char *)align_ptr_up ( aligned_heap_base_min_address , attach_point_alignment); + try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, large); + } + + // zerobased: Attempt to allocate in the lower 32G. + // But leave room for the compressed class pointers, which is allocated above + // the heap. + char *zerobased_max = (char *)OopEncodingHeapMax; + // For small heaps, save some space for compressed class pointer + // space so it can be decoded with no base. + if (UseCompressedClassPointers && !UseSharedSpaces && + OopEncodingHeapMax <= KlassEncodingMetaspaceMax) { + const size_t class_space = align_size_up(CompressedClassSpaceSize, alignment); + zerobased_max = (char *)OopEncodingHeapMax - class_space; + } + + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= zerobased_max && // Zerobased theoretical possible. + ((_base == NULL) || // No previous try succeeded. + (_base + size > zerobased_max))) { // Unscaled delivered an arbitrary address. + + // Calc address range within we try to attach (range of possible start addresses). + char *const highest_start = (char *)align_ptr_down(zerobased_max - size, attach_point_alignment); + // SS10 and SS12u1 cannot compile "(char *)UnscaledOopHeapMax - size" on solaris sparc 32-bit: + // "Cannot use int to initialize char*." Introduce aux variable. + char *unscaled_end = (char *)UnscaledOopHeapMax; + unscaled_end -= size; + char *lowest_start = (size < UnscaledOopHeapMax) ? + MAX2(unscaled_end, aligned_heap_base_min_address) : aligned_heap_base_min_address; + lowest_start = (char *)align_ptr_up(lowest_start, attach_point_alignment); + try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, zerobased_max, size, alignment, large); + } + + // Now we go for heaps with base != 0. We need a noaccess prefix to efficiently + // implement null checks. + noaccess_prefix = noaccess_prefix_size(alignment); + + // Try to attach at addresses that are aligned to OopEncodingHeapMax. Disjointbase mode. + char** addresses = get_attach_addresses_for_disjoint_mode(); + int i = 0; + while (addresses[i] && // End of array not yet reached. + ((_base == NULL) || // No previous try succeeded. + (_base + size > (char *)OopEncodingHeapMax && // Not zerobased or unscaled address. + !Universe::is_disjoint_heap_base_address((address)_base)))) { // Not disjoint address. + char* const attach_point = addresses[i]; + assert(attach_point >= aligned_heap_base_min_address, "Flag support broken"); + try_reserve_heap(size + noaccess_prefix, alignment, large, attach_point); + i++; + } + + // Last, desperate try without any placement. + if (_base == NULL) { + if (PrintCompressedOopsMode && Verbose) { + tty->print("Trying to allocate at address NULL heap of size " PTR_FORMAT ".\n", (address)size + noaccess_prefix); + } + initialize(size + noaccess_prefix, alignment, large, NULL, false); + } + } +} + +ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large) : ReservedSpace() { + + if (size == 0) { + return; + } + + // Heap size should be aligned to alignment, too. + guarantee(is_size_aligned(size, alignment), "set by caller"); + + if (UseCompressedOops) { + initialize_compressed_heap(size, alignment, large); + if (_size > size) { + // We allocated heap with noaccess prefix. + // It can happen we get a zerobased/unscaled heap with noaccess prefix, + // if we had to try at arbitrary address. + establish_noaccess_prefix(); + } + } else { + initialize(size, alignment, large, NULL, false); + } + + assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, + "area must be distinguishable from marks for mark-sweep"); + assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], + "area must be distinguishable from marks for mark-sweep"); + if (base() > 0) { MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap); } - - // Only reserved space for the java heap should have a noaccess_prefix - // if using compressed oops. - protect_noaccess_prefix(size); } // Reserve space for code segment. Same as Java heap only we mark this as @@ -791,8 +1051,7 @@ class TestReservedSpace : AllStatic { ReservedSpace rs(size, // size alignment, // alignment UseLargePages, // large - NULL, // requested_address - 0); // noacces_prefix + (char *)NULL); // requested_address test_log(" rs.special() == %d", rs.special()); diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index e614d0d6793..8c2b4ac6d10 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,33 +31,29 @@ class ReservedSpace VALUE_OBJ_CLASS_SPEC { friend class VMStructs; - private: + protected: char* _base; size_t _size; size_t _noaccess_prefix; size_t _alignment; bool _special; + private: bool _executable; // ReservedSpace ReservedSpace(char* base, size_t size, size_t alignment, bool special, bool executable); + protected: void initialize(size_t size, size_t alignment, bool large, char* requested_address, - const size_t noaccess_prefix, bool executable); - protected: - // Create protection page at the beginning of the space. - void protect_noaccess_prefix(const size_t size); - public: // Constructor ReservedSpace(); ReservedSpace(size_t size); ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address = NULL, - const size_t noaccess_prefix = 0); + char* requested_address = NULL); ReservedSpace(size_t size, size_t alignment, bool large, bool executable); // Accessors @@ -98,12 +94,23 @@ ReservedSpace ReservedSpace::last_part(size_t partition_size) return last_part(partition_size, alignment()); } -// Class encapsulating behavior specific of memory space reserved for Java heap +// Class encapsulating behavior specific of memory space reserved for Java heap. class ReservedHeapSpace : public ReservedSpace { -public: - // Constructor - ReservedHeapSpace(size_t size, size_t forced_base_alignment, - bool large, char* requested_address); + private: + void try_reserve_heap(size_t size, size_t alignment, bool large, + char *requested_address); + void try_reserve_range(char *highest_start, char *lowest_start, + size_t attach_point_alignment, char *aligned_HBMA, + char *upper_bound, size_t size, size_t alignment, bool large); + void initialize_compressed_heap(const size_t size, size_t alignment, bool large); + // Create protection page at the beginning of the space. + void establish_noaccess_prefix(); + public: + // Constructor. Tries to find a heap that is good for compressed oops. + ReservedHeapSpace(size_t size, size_t forced_base_alignment, bool large); + // Returns the base to be used for compression, i.e. so that null can be + // encoded safely and implicit null checks can work. + char *compressed_oop_base() { return _base - _noaccess_prefix; } }; // Class encapsulating behavior specific memory space for Code diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 318c62b4708..784db46775d 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,9 +124,6 @@ extern int LogBitsPerHeapOop; extern int BytesPerHeapOop; extern int BitsPerHeapOop; -// Oop encoding heap max -extern uint64_t OopEncodingHeapMax; - const int BitsPerJavaInteger = 32; const int BitsPerJavaLong = 64; const int BitsPerSize_t = size_tSize * BitsPerByte; @@ -195,7 +192,6 @@ inline size_t heap_word_size(size_t byte_size) { return (byte_size + (HeapWordSize-1)) >> LogHeapWordSize; } - const size_t K = 1024; const size_t M = K*K; const size_t G = M*K; @@ -397,8 +393,17 @@ const int LogKlassAlignment = LogKlassAlignmentInBytes - LogHeapWordSize; const int KlassAlignmentInBytes = 1 << LogKlassAlignmentInBytes; const int KlassAlignment = KlassAlignmentInBytes / HeapWordSize; -// Klass encoding metaspace max size -const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; +// Maximal size of heap where unscaled compression can be used. Also upper bound +// for heap placement: 4GB. +const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); +// Maximal size of heap where compressed oops can be used. Also upper bound for heap +// placement for zero based compression algorithm: UnscaledOopHeapMax << LogMinObjAlignmentInBytes. +extern uint64_t OopEncodingHeapMax; + +// Maximal size of compressed class space. Above this limit compression is not possible. +// Also upper bound for placement of zero based class space. (Class space is further limited +// to be < 3G, see arguments.cpp.) +const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; // Machine dependent stuff diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp index ad71883f81d..32094ab8635 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2013 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -172,21 +172,21 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } #define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16) // Some constant sizes used throughout the AIX port -#define SIZE_1K ((uint64_t) 0x400ULL) -#define SIZE_4K ((uint64_t) 0x1000ULL) -#define SIZE_64K ((uint64_t) 0x10000ULL) -#define SIZE_1M ((uint64_t) 0x100000ULL) -#define SIZE_4M ((uint64_t) 0x400000ULL) -#define SIZE_8M ((uint64_t) 0x800000ULL) -#define SIZE_16M ((uint64_t) 0x1000000ULL) -#define SIZE_256M ((uint64_t) 0x10000000ULL) -#define SIZE_1G ((uint64_t) 0x40000000ULL) -#define SIZE_2G ((uint64_t) 0x80000000ULL) -#define SIZE_4G ((uint64_t) 0x100000000ULL) -#define SIZE_16G ((uint64_t) 0x400000000ULL) -#define SIZE_32G ((uint64_t) 0x800000000ULL) -#define SIZE_64G ((uint64_t) 0x1000000000ULL) -#define SIZE_1T ((uint64_t) 0x10000000000ULL) +#define SIZE_1K ((uint64_t) UCONST64( 0x400)) +#define SIZE_4K ((uint64_t) UCONST64( 0x1000)) +#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) +#define SIZE_1M ((uint64_t) UCONST64( 0x100000)) +#define SIZE_4M ((uint64_t) UCONST64( 0x400000)) +#define SIZE_8M ((uint64_t) UCONST64( 0x800000)) +#define SIZE_16M ((uint64_t) UCONST64( 0x1000000)) +#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) +#define SIZE_1G ((uint64_t) UCONST64( 0x40000000)) +#define SIZE_2G ((uint64_t) UCONST64( 0x80000000)) +#define SIZE_4G ((uint64_t) UCONST64( 0x100000000)) +#define SIZE_16G ((uint64_t) UCONST64( 0x400000000)) +#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) +#define SIZE_64G ((uint64_t) UCONST64( 0x1000000000)) +#define SIZE_1T ((uint64_t) UCONST64(0x10000000000)) #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP diff --git a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java index 6f3e21c0e73..edc3d336420 100644 --- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java +++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java @@ -35,20 +35,42 @@ import com.oracle.java.testlibrary.*; public class UseCompressedOops { public static void main(String[] args) throws Exception { + testCompressedOopsModesGCs(); + testCompressedOopsModesGCs("-XX:+UseLargePages"); + } + + public static void testCompressedOopsModesGCs(String... flags) throws Exception { + ArrayList args = new ArrayList<>(); + Collections.addAll(args, flags); + + // Test default. + testCompressedOopsModes(args); + // Test GCs. + testCompressedOopsModes(args, "-XX:+UseG1GC"); + testCompressedOopsModes(args, "-XX:+UseConcMarkSweepGC"); + testCompressedOopsModes(args, "-XX:+UseSerialGC"); + testCompressedOopsModes(args, "-XX:+UseParallelGC"); + testCompressedOopsModes(args, "-XX:+UseParallelOldGC"); + } + + public static void testCompressedOopsModes(ArrayList flags1, String... flags2) throws Exception { + ArrayList args = new ArrayList<>(); + args.addAll(flags1); + Collections.addAll(args, flags2); if (Platform.is64bit()) { // Explicitly turn of compressed oops - testCompressedOops("-XX:-UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:-UseCompressedOops", "-Xmx32m") .shouldNotContain("Compressed Oops") .shouldHaveExitValue(0); // Compressed oops should be on by default - testCompressedOops("-Xmx32m") + testCompressedOops(args, "-Xmx32m") .shouldContain("Compressed Oops mode") .shouldHaveExitValue(0); // Explicly enabling compressed oops - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") .shouldContain("Compressed Oops mode") .shouldHaveExitValue(0); @@ -58,68 +80,89 @@ public class UseCompressedOops { // puts the heap way up, forcing different behaviour. if (!Platform.isOSX() && !Platform.isSolaris()) { // Larger than 4gb heap should result in zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx5g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx5g") + .shouldContain("Zero based") + .shouldContain("Oop shift amount: 3") + .shouldHaveExitValue(0); + + // Larger than 3gb heap and HeapBaseMinAddress=1g should result in zero based with shift 3 + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx3200m", "-XX:HeapBaseMinAddress=1g") .shouldContain("Zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // Small heap above 4gb should result in zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=4g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=4g") .shouldContain("Zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // Small heap above 32gb should result in non-zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=32g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=32g") + .shouldContain("Non-zero disjoint base") + .shouldContain("Oop shift amount: 3") + .shouldHaveExitValue(0); + + // Small heap above 32gb should result in non-zero based with shift 3 + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=72704m") .shouldContain("Non-zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // 32gb heap with heap base above 64gb and object alignment set to 16 bytes should result // in non-zero based with shift 4 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16", + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16", "-XX:HeapBaseMinAddress=64g") - .shouldContain("Non-zero based") + .shouldContain("Non-zero disjoint base") .shouldContain("Oop shift amount: 4") .shouldHaveExitValue(0); // 32gb heap with object alignment set to 16 bytes should result in zero based with shift 4 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16") .shouldContain("Zero based") .shouldContain("Oop shift amount: 4") .shouldHaveExitValue(0); } + // This is a pathologic case for the heap allocation algorithm. Regression test. + // HeapBaseMinAddress must be 2g and should not be set on the command line. + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx2g") + .shouldNotContain("Max heap size too large for Compressed Oops") + .shouldHaveExitValue(0); + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx29g", "-XX:CompressedClassSpaceSize=1g") + .shouldNotContain("Max heap size too large for Compressed Oops") + .shouldHaveExitValue(0); + // Explicitly enabling compressed oops with 32gb heap should result a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // 32gb heap should not result a warning - testCompressedOops("-Xmx32g") + testCompressedOops(args, "-Xmx32g") .shouldNotContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // Explicitly enabling compressed oops with 32gb heap and object // alignment set to 8 byte should result a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=8") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=8") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // 64gb heap and object alignment set to 16 bytes should result in a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx64g", "-XX:ObjectAlignmentInBytes=16") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx64g", "-XX:ObjectAlignmentInBytes=16") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); } else { // Compressed oops should only apply to 64bit platforms - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") .shouldContain("Unrecognized VM option 'UseCompressedOops'") .shouldHaveExitValue(1); } } - private static OutputAnalyzer testCompressedOops(String... flags) throws Exception { + private static OutputAnalyzer testCompressedOops(ArrayList flags1, String... flags2) throws Exception { ArrayList args = new ArrayList<>(); // Always run with these three: @@ -128,7 +171,8 @@ public class UseCompressedOops { args.add("-Xms32m"); // Add the extra flags - Collections.addAll(args, flags); + args.addAll(flags1); + Collections.addAll(args, flags2); args.add("-version"); From 2b871d6987cc7e54936033d10b1e313f5c27ba82 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 5 Jan 2015 22:50:59 -0500 Subject: [PATCH 32/72] 6583051: crash when adding non-static methods to java.lang.Object class Stop the JVM if java.lang.Object is incorrectly defined rather than crashing. Reviewed-by: ctornqvi, dholmes --- hotspot/src/share/vm/oops/klassVtable.cpp | 26 ++++++----- .../BadObjectClass/BootstrapRedefine.java | 44 +++++++++++++++++++ .../test/runtime/BadObjectClass/Object.java | 37 ++++++++++++++++ 3 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java create mode 100644 hotspot/test/runtime/BadObjectClass/Object.java diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index 7f8fee0f80b..6978247d318 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,17 +100,21 @@ void klassVtable::compute_vtable_size_and_num_mirandas( vtable_length = Universe::base_vtable_size(); } - if (super == NULL && !Universe::is_bootstrapping() && - vtable_length != Universe::base_vtable_size()) { - // Someone is attempting to redefine java.lang.Object incorrectly. The - // only way this should happen is from - // SystemDictionary::resolve_from_stream(), which will detect this later - // and throw a security exception. So don't assert here to let - // the exception occur. - vtable_length = Universe::base_vtable_size(); + if (super == NULL && vtable_length != Universe::base_vtable_size()) { + if (Universe::is_bootstrapping()) { + // Someone is attempting to override java.lang.Object incorrectly on the + // bootclasspath. The JVM cannot recover from this error including throwing + // an exception + vm_exit_during_initialization("Incompatible definition of java.lang.Object"); + } else { + // Someone is attempting to redefine java.lang.Object incorrectly. The + // only way this should happen is from + // SystemDictionary::resolve_from_stream(), which will detect this later + // and throw a security exception. So don't assert here to let + // the exception occur. + vtable_length = Universe::base_vtable_size(); + } } - assert(super != NULL || vtable_length == Universe::base_vtable_size(), - "bad vtable size for class Object"); assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); diff --git a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java new file mode 100644 index 00000000000..08ed2f09366 --- /dev/null +++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6583051 + * @summary Give error if java.lang.Object has been incompatibly overridden on the bootpath + * @library /testlibrary + * @compile Object.java + * @run main BootstrapRedefine + */ + +import com.oracle.java.testlibrary.*; + +public class BootstrapRedefine { + + public static void main(String[] args) throws Exception { + String testClasses = System.getProperty("test.classes", "."); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/p:" + testClasses, "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Incompatible definition of java.lang.Object") + .shouldHaveExitValue(1); + } +} diff --git a/hotspot/test/runtime/BadObjectClass/Object.java b/hotspot/test/runtime/BadObjectClass/Object.java new file mode 100644 index 00000000000..b2ad19b6b99 --- /dev/null +++ b/hotspot/test/runtime/BadObjectClass/Object.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +/** + * This is a fake java.lang.Object class. + */ +public class Object { + + // Add some methods + void dummy1() { return; } + void dummy2() { return; } + void dummy3() { return; } +} From e268dee36122e264639e1ccb5f267567b59b0a6f Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Tue, 13 Jan 2015 14:26:34 +0300 Subject: [PATCH 33/72] 8048603: Additional tests for MAC algorithms Reviewed-by: valeriep --- .../provider/Mac/EmptyByteBufferTest.java | 65 +++++ .../provider/Mac/LargeByteBufferTest.java | 89 ++++++ .../sun/crypto/provider/Mac/MacSameTest.java | 100 +++++++ .../provider/Mac/NullByteBufferTest.java | 69 +++++ .../com/sun/crypto/provider/Mac/Utils.java | 79 ++++++ jdk/test/sun/security/pkcs11/Mac/MacKAT.java | 265 ++++++++++++++++++ .../sun/security/pkcs11/Mac/MacSameTest.java | 125 +++++++++ jdk/test/sun/security/pkcs11/PKCS11Test.java | 17 ++ 8 files changed, 809 insertions(+) create mode 100644 jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java create mode 100644 jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java create mode 100644 jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java create mode 100644 jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java create mode 100644 jdk/test/com/sun/crypto/provider/Mac/Utils.java create mode 100644 jdk/test/sun/security/pkcs11/Mac/MacKAT.java create mode 100644 jdk/test/sun/security/pkcs11/Mac/MacSameTest.java diff --git a/jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java b/jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java new file mode 100644 index 00000000000..9b1dd1cb373 --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if MAC algorithms work fine with empty buffer + * @author Alexander Fomin + * @build Utils + * @run main EmptyByteBufferTest + */ +public class EmptyByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new EmptyByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[0]; + ByteBuffer buf = ByteBuffer.wrap(data); + + mac.update(buf); + mac.doFinal(); + } + +} diff --git a/jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java b/jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java new file mode 100644 index 00000000000..f294b67743b --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with large buffer + * @author Alexander Fomin + * @build Utils + * @run main LargeByteBufferTest + */ +public class LargeByteBufferTest implements MacTest { + + private static final int BUFFER_SIZE = 65535; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new LargeByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[BUFFER_SIZE]; + for (int i = 0; i < BUFFER_SIZE; i++) { + data[i] = (byte) (i % 256); + } + + ByteBuffer buf = ByteBuffer.wrap(data); + int limitBefore = buf.limit(); + + mac.update(buf); + mac.doFinal(); + + int limitAfter = buf.limit(); + int positonAfter = buf.position(); + + if (limitAfter != limitBefore) { + System.out.println("limit after = " + limitAfter); + System.out.println("limit before = " + limitBefore); + throw new RuntimeException("Test failed: " + + "limit of buffer has been chenged."); + } + + if (positonAfter != limitAfter) { + System.out.println("position after = " + positonAfter); + System.out.println("limit after = " + limitAfter); + throw new RuntimeException("Test failed: " + + "position of buffer isn't equal to its limit"); + } + } + +} diff --git a/jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java b/jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java new file mode 100644 index 00000000000..8d97f1a6a88 --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @build Utils + * @run main MacSameTest + */ +public class MacSameTest implements MacTest { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new MacSameTest()); + } + + @Override + public void doTest(String algo) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidKeyException { + Mac mac; + try { + mac = Mac.getInstance(algo, "SunJCE"); + } catch (NoSuchAlgorithmException nsae) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff --git a/jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java b/jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java new file mode 100644 index 00000000000..d71d4f96317 --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with null buffer + * @author Alexander Fomin + * @build Utils + * @run main NullByteBufferTest + */ +public class NullByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new NullByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + try { + ByteBuffer buf = null; + mac.update(buf); + mac.doFinal(); + throw new RuntimeException( + "Expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("Expected IllegalArgumentException thrown: " + + e); + } + } + +} diff --git a/jdk/test/com/sun/crypto/provider/Mac/Utils.java b/jdk/test/com/sun/crypto/provider/Mac/Utils.java new file mode 100644 index 00000000000..389d40b0d14 --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/Mac/Utils.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.SecureRandom; +import javax.crypto.spec.SecretKeySpec; + +/** + * Helper class. + */ +class Utils { + + static final int KEY_SIZE = 70; + + static final String[] MAC_ALGOS = {"HmacMD5", "HmacSHA1", "HmacSHA224", + "HmacSHA256", "HmacSHA384", "HmacSHA512"}; + + /** + * Get SecretKeySpec. + */ + static SecretKeySpec getSecretKeySpec() { + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + return new SecretKeySpec(keyVal, "HMAC"); + } + + static void runTests(MacTest... tests) { + boolean success = true; + for (MacTest test : tests) { + success &= runTest(test); + } + + if (success) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("Test failed"); + } + } + + private static boolean runTest(MacTest test) { + boolean success = true; + for (String alg : MAC_ALGOS) { + try { + System.out.println("Test " + alg); + test.doTest(alg); + } catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + success = false; + } + } + + return success; + } +} + +interface MacTest { + void doTest(String alg) throws Exception; +} \ No newline at end of file diff --git a/jdk/test/sun/security/pkcs11/Mac/MacKAT.java b/jdk/test/sun/security/pkcs11/Mac/MacKAT.java new file mode 100644 index 00000000000..c7da9297159 --- /dev/null +++ b/jdk/test/sun/security/pkcs11/Mac/MacKAT.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.UnsupportedEncodingException; +import java.security.Provider; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 4846410 6313661 4963723 + * @summary Basic known-answer-test for Hmac algorithms + * @author Andreas Sterbenz + * @library .. + * @run main MacKAT + */ +public class MacKAT extends PKCS11Test { + + private final static byte[] ALONG, BLONG, BKEY, BKEY_20, DDDATA_50, + AAKEY_20, CDDATA_50, AAKEY_131; + + static { + ALONG = new byte[1024 * 128]; + Arrays.fill(ALONG, (byte)'a'); + BLONG = new byte[1024 * 128]; + Random random = new Random(12345678); + random.nextBytes(BLONG); + BKEY = new byte[128]; + random.nextBytes(BKEY); + BKEY_20 = new byte[20]; + Arrays.fill(BKEY_20, (byte) 0x0b); + DDDATA_50 = new byte[50]; + Arrays.fill(DDDATA_50, (byte) 0xdd); + AAKEY_20 = new byte[20]; + Arrays.fill(AAKEY_20, (byte) 0xaa); + CDDATA_50 = new byte[50]; + Arrays.fill(CDDATA_50, (byte) 0xcd); + AAKEY_131 = new byte[131]; + Arrays.fill(AAKEY_131, (byte) 0xaa); + } + + private final static Test[] tests = { + newMacTest("SslMacMD5", + ALONG, + "f4:ad:01:71:51:f6:89:56:72:a3:32:bf:d9:2a:f2:a5", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("SslMacMD5", + BLONG, + "34:1c:ad:a0:95:57:32:f8:8e:80:8f:ee:b2:d8:23:e5", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("SslMacSHA1", + ALONG, + "11:c1:71:2e:61:be:4b:cf:bc:6d:e2:4c:58:ae:27:30:0b:24:a4:87", + "23:ae:dd:61:87:6c:7a:45:47:2f:2c:8f:ea:64:99:3e:27:5f:97:a5"), + newMacTest("SslMacSHA1", + BLONG, + "84:af:57:0a:af:ef:16:93:90:50:da:88:f8:ad:1a:c5:66:6c:94:d0", + "9b:bb:e2:aa:9b:28:1c:95:0e:ea:30:21:98:a5:7e:31:9e:bf:5f:51"), + newMacTest("HmacMD5", + ALONG, + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacMD5", + BLONG, + "6c:22:79:bb:34:9e:da:f4:f5:cf:df:0c:62:3d:59:e0", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacMD5", + BLONG, + "e6:ad:00:c9:49:6b:98:fe:53:a2:b9:2d:7d:41:a2:03", + BKEY), + newMacTest("HmacSHA1", + ALONG, + "9e:b3:6e:35:fa:fb:17:2e:2b:f3:b0:4a:9d:38:83:c4:5f:6d:d9:00", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA1", + BLONG, + "80:2d:5b:ea:08:df:a4:1f:e5:3e:1c:fa:fc:ad:dd:31:da:15:60:2c", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacSHA1", + BLONG, + "a2:fa:2a:85:18:0e:94:b2:a5:e2:17:8b:2a:29:7a:95:cd:e8:aa:82", + BKEY), + newMacTest("HmacSHA256", + ALONG, + "3f:6d:08:df:0c:90:b0:e9:ed:13:4a:2e:c3:48:1d:3d:3e:61:2e:f1:" + + "30:c2:63:c4:58:57:03:c2:cb:87:15:07", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA256", + BLONG, + "e2:4e:a3:b9:0b:b8:99:e4:71:cf:ca:9f:f8:4e:f0:34:8b:19:9f:33:" + + "4b:1a:b7:13:f7:c8:57:92:e3:03:74:78", + BKEY), + newMacTest("HmacSHA384", + ALONG, + "d0:f0:d4:54:1c:0a:6d:81:ed:15:20:d7:0c:96:06:61:a0:ff:c9:ff:" + + "91:e9:a0:cd:e2:45:64:9d:93:4c:a9:fa:89:ae:c0:90:e6:" + + "0b:a1:a0:56:80:57:3b:ed:4b:b0:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA384", + BLONG, + "75:c4:ca:c7:f7:58:9d:d3:23:b1:1b:5c:93:2d:ec:7a:03:dc:8c:eb:" + + "8d:fe:79:46:4f:30:e7:99:62:de:44:e2:38:95:0e:79:91:" + + "78:2f:a4:05:0a:f0:17:10:38:a1:8e", + BKEY), + newMacTest("HmacSHA512", + ALONG, + "41:ea:4c:e5:31:3f:7c:18:0e:5e:95:a9:25:0a:10:58:e6:40:53:88:" + + "82:4f:5a:da:6f:29:de:04:7b:8e:d7:ed:7c:4d:b8:2a:48:" + + "2d:17:2a:2d:59:bb:81:9c:bf:33:40:04:77:44:fb:45:25:" + + "1f:fd:b9:29:f4:a6:69:a3:43:6f", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA512", + BLONG, + "fb:cf:4b:c6:d5:49:5a:5b:0b:d9:2a:32:f5:fa:68:d2:68:a4:0f:ae:" + + "53:fc:49:12:e6:1d:53:cf:b2:cb:c5:c5:f2:2d:86:bd:14:" + + "61:30:c3:a6:6f:44:1f:77:9b:aa:a1:22:48:a9:dd:d0:45:" + + "86:d1:a1:82:53:13:c4:03:06:a3", + BKEY), + + // Test vectors From RFC 4231 + newMacTest("HmacSHA224", + bytes("Hi There"), + "89:6f:b1:12:8a:bb:df:19:68:32:10:7c:d4:9d:f3:3f:47:b4:b1:16:" + + "99:12:ba:4f:53:68:4b:22", + BKEY_20), + newMacTest("HmacSHA224", + bytes("what do ya want for nothing?"), + "a3:0e:01:09:8b:c6:db:bf:45:69:0f:3a:7e:9e:6d:0f:8b:be:a2:a3:" + + "9e:61:48:00:8f:d0:5e:44", + bytes("Jefe")), + newMacTest("HmacSHA224", + DDDATA_50, + "7f:b3:cb:35:88:c6:c1:f6:ff:a9:69:4d:7d:6a:d2:64:93:65:b0:c1:" + + "f6:5d:69:d1:ec:83:33:ea", + AAKEY_20), + newMacTest("HmacSHA224", + CDDATA_50, + "6c:11:50:68:74:01:3c:ac:6a:2a:bc:1b:b3:82:62:7c:ec:6a:90:d8:" + + "6e:fc:01:2d:e7:af:ec:5a", + "01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:" + + "15:16:17:18:19"), + newMacTest("HmacSHA224", + bytes("Test Using Larger Than Block-Size Key - Hash Key First"), + "95:e9:a0:db:96:20:95:ad:ae:be:9b:2d:6f:0d:bc:e2:d4:99:f1:12:" + + "f2:d2:b7:27:3f:a6:87:0e", + AAKEY_131), + newMacTest("HmacSHA224", + bytes("This is a test using a larger than block-size key and " + + "a larger than block-size data. The key needs to be " + + "hashed before being used by the HMAC algorithm."), + "3a:85:41:66:ac:5d:9f:02:3f:54:d5:17:d0:b3:9d:bd:94:67:70:db:" + + "9c:2b:95:c9:f6:f5:65:d1", + AAKEY_131), + }; + + public static void main(String[] args) throws Exception { + main(new MacKAT()); + } + + @Override + public void main(Provider p) throws Exception { + long start = System.currentTimeMillis(); + + List algorithms = getSupportedAlgorithms("Mac", "", p); + for (Test test : tests) { + if(!algorithms.contains(test.getAlg())) { + continue; + } + test.run(p); + } + + System.out.println("All tests passed"); + long stop = System.currentTimeMillis(); + System.out.println("Done (" + (stop - start) + " ms)."); + } + + private static byte[] bytes(String s) { + try { + return s.getBytes("UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + String key) { + return new MacTest(alg, input, parse(macvalue), parse(key)); + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + byte[] key) { + return new MacTest(alg, input, parse(macvalue), key); + } + + interface Test { + void run(Provider p) throws Exception; + String getAlg(); + } + + static class MacTest implements Test { + private final String alg; + private final byte[] input; + private final byte[] macvalue; + private final byte[] key; + + MacTest(String alg, byte[] input, byte[] macvalue, byte[] key) { + this.alg = alg; + this.input = input; + this.macvalue = macvalue; + this.key = key; + } + + @Override + public String getAlg() { + return alg; + } + + @Override + public void run(Provider p) throws Exception { + Mac mac = Mac.getInstance(alg, p); + SecretKey keySpec = new SecretKeySpec(key, alg); + mac.init(keySpec); + mac.update(input); + byte[] macv = mac.doFinal(); + if (Arrays.equals(macvalue, macv) == false) { + System.out.println("Mac test for " + alg + " failed:"); + if (input.length < 256) { + System.out.println("input: " + + PKCS11Test.toString(input)); + } + System.out.println("key: " + PKCS11Test.toString(key)); + System.out.println("macvalue: " + + PKCS11Test.toString(macvalue)); + System.out.println("calculated: " + PKCS11Test.toString(macv)); + throw new Exception("Mac test for " + alg + " failed"); + } + System.out.println("passed: " + alg); + } + } + +} diff --git a/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java b/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java new file mode 100644 index 00000000000..f5e2787e609 --- /dev/null +++ b/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; +import java.util.List; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @library .. + * @run main MacSameTest + */ +public class MacSameTest extends PKCS11Test { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) throws Exception { + main(new MacSameTest()); + } + + @Override + public void main(Provider p) { + List algorithms = getSupportedAlgorithms("Mac", "Hmac", p); + boolean success = true; + for (String alg : algorithms) { + try { + doTest(alg, p); + } catch (Exception e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(); + success = false; + } + } + + if (!success) { + throw new RuntimeException("Test failed"); + } + } + + private void doTest(String algo, Provider provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException { + System.out.println("Test " + algo); + Mac mac; + try { + mac = Mac.getInstance(algo, provider); + } catch (NoSuchAlgorithmException nsae) { + if ("SunPKCS11-Solaris".equals(provider.getName())) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + throw nsae; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff --git a/jdk/test/sun/security/pkcs11/PKCS11Test.java b/jdk/test/sun/security/pkcs11/PKCS11Test.java index dbdd3d370fb..57651b27baa 100644 --- a/jdk/test/sun/security/pkcs11/PKCS11Test.java +++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java @@ -582,4 +582,21 @@ public abstract class PKCS11Test { return r; } + /** + * Returns supported algorithms of specified type. + */ + static List getSupportedAlgorithms(String type, String alg, + Provider p) { + // prepare a list of supported algorithms + List algorithms = new ArrayList<>(); + Set services = p.getServices(); + for (Provider.Service service : services) { + if (service.getType().equals(type) + && service.getAlgorithm().startsWith(alg)) { + algorithms.add(service.getAlgorithm()); + } + } + return algorithms; + } + } From cf89eaf43d2d5fcfeead423ff5a4da2eb97f4abf Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Tue, 13 Jan 2015 14:35:39 +0100 Subject: [PATCH 34/72] 8068774: CounterMonitorDeadlockTest.java timed out Reviewed-by: jbachorik, dfuchs --- .../monitor/CounterMonitorDeadlockTest.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java b/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java index 764d2733d60..f241ccf7d3a 100644 --- a/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java +++ b/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicInteger; -import javax.management.Attribute; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.Notification; @@ -95,18 +94,16 @@ public class CounterMonitorDeadlockTest { monitorProxy.setInitThreshold(100); monitorProxy.setGranularityPeriod(10L); // 10 ms monitorProxy.setNotify(true); - monitorProxy.start(); final int initGetCount = observedProxy.getGetCount(); - int getCount; + monitorProxy.start(); + System.out.println("Checking GetCount, possible deadlock if timeout."); do { // 8038322. Until timeout of testing harness Thread.sleep(200); - } while ((getCount=observedProxy.getGetCount()) == initGetCount); + } while ((observedProxy.getGetCount()) == initGetCount); System.out.println("Done!"); - if (getCount <= initGetCount) - throw new Exception("Test failed: presumable deadlock"); // This won't show up as a deadlock in CTRL-\ or in // ThreadMXBean.findDeadlockedThreads(), because they don't // see that thread A is waiting for thread B (B.join()), and From 3b573293b8e8b6e6e4e915edf9d07d71640402ed Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Tue, 13 Jan 2015 07:57:51 -0800 Subject: [PATCH 35/72] 8067344: Adjust java/lang/invoke/LFCaching/LFGarbageCollectedTest.java for recent changes in java.lang.invoke Reviewed-by: psandoz --- .../LFCaching/LFGarbageCollectedTest.java | 82 +++++++++++++++---- .../invoke/LFCaching/LambdaFormTestCase.java | 21 +++-- 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java index 89a1ecf8e91..415be4621b7 100644 --- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java +++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java @@ -30,11 +30,13 @@ * @build TestMethods * @build LambdaFormTestCase * @build LFGarbageCollectedTest - * @run main/othervm LFGarbageCollectedTest + * @run main/othervm -Xmx64m -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+HeapDumpOnOutOfMemoryError -DHEAP_DUMP=false LFGarbageCollectedTest */ import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.InvocationTargetException; import java.util.EnumSet; @@ -44,6 +46,7 @@ import java.util.Map; * Lambda forms garbage collection test class. */ public final class LFGarbageCollectedTest extends LambdaFormTestCase { + private static boolean HEAP_DUMP = Boolean.getBoolean("HEAP_DUMP"); /** * Constructor for a lambda forms garbage collection test case. @@ -55,37 +58,86 @@ public final class LFGarbageCollectedTest extends LambdaFormTestCase { super(testMethod); } + PhantomReference ph; + ReferenceQueue rq = new ReferenceQueue(); + MethodType mtype; + Map data; + @Override public void doTest() { try { - Map data = getTestMethod().getTestCaseData(); + TestMethods testCase = getTestMethod(); + data = testCase.getTestCaseData(); MethodHandle adapter; try { - adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE); + adapter = testCase.getTestCaseMH(data, TestMethods.Kind.ONE); } catch (NoSuchMethodException ex) { throw new Error("Unexpected exception: ", ex); } - Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter); + mtype = adapter.type(); + Object lambdaForm = INTERNAL_FORM.invoke(adapter); if (lambdaForm == null) { throw new Error("Unexpected error: Lambda form of the method handle is null"); } - ReferenceQueue rq = new ReferenceQueue(); - PhantomReference ph = new PhantomReference(lambdaForm, rq); + + String debugName = (String)DEBUG_NAME.get(lambdaForm); + if (debugName != null && debugName.startsWith("identity_")) { + // Ignore identity_* LambdaForms. + return; + } + + ph = new PhantomReference(lambdaForm, rq); lambdaForm = null; - data = null; adapter = null; - for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) { - System.gc(); - } - if (!ph.isEnqueued()) { - throw new AssertionError("Error: Lambda form is not garbage collected"); - } + + collectLambdaForm(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new Error("Unexpected exception: ", ex); } } + + private void collectLambdaForm() throws IllegalAccessException { + // Usually, 2 System.GCs are necessary to enqueue a SoftReference. + System.gc(); + System.gc(); + + Reference ref = null; + for (int i = 0; i < 10; i++) { + try { + ref = rq.remove(1000); + } catch (InterruptedException e) { + /* ignore */ + } + if (ref != null) { + break; + } + System.gc(); // If the reference hasn't been queued yet, trigger one more GC. + } + + if (ref == null) { + dumpTestData(); + System.err.println("Method type: " + mtype); + System.err.println("LambdaForm: " + REF_FIELD.get(ph)); + + if (HEAP_DUMP) { + // Trigger OOM to force heap dump for post-mortem analysis. + val = new long[1_000_000_000]; + } + throw new AssertionError("Error: LambdaForm is not garbage collected"); + }; + } + + private void dumpTestData() { + System.err.println("Test case: " + getTestMethod()); + for (String s : data.keySet()) { + System.err.printf("\t%20s => %s\n", s, data.get(s)); + } + } + + private static long[] val; + /** * Main routine for lambda forms garbage collection test. * @@ -101,7 +153,9 @@ public final class LFGarbageCollectedTest extends LambdaFormTestCase { TestMethods.IDENTITY, TestMethods.CONSTANT, TestMethods.ARRAY_ELEMENT_GETTER, - TestMethods.ARRAY_ELEMENT_SETTER)); + TestMethods.ARRAY_ELEMENT_SETTER, + TestMethods.EXACT_INVOKER, + TestMethods.INVOKER)); LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods); } } diff --git a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java index 9fcc45eae3f..f3fb33bd9f3 100644 --- a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java +++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java @@ -23,9 +23,11 @@ import com.oracle.testlibrary.jsr292.Helper; import com.sun.management.HotSpotDiagnosticMXBean; - +import java.lang.invoke.MethodHandle; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; +import java.lang.ref.Reference; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; @@ -42,8 +44,6 @@ import jdk.testlibrary.TimeLimitedRunner; */ public abstract class LambdaFormTestCase { - private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle"; - private final static String INTERNAL_FORM_METHOD_NAME = "internalForm"; private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO = 45 / (128.0 * 1024 * 1024); private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9); @@ -53,6 +53,8 @@ public abstract class LambdaFormTestCase { * used to get a lambda form from a method handle. */ protected final static Method INTERNAL_FORM; + protected final static Field DEBUG_NAME; + protected final static Field REF_FIELD; private static final List gcInfo; private static long gcCount() { @@ -61,9 +63,14 @@ public abstract class LambdaFormTestCase { static { try { - Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME); - INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME); + INTERNAL_FORM = MethodHandle.class.getDeclaredMethod("internalForm"); INTERNAL_FORM.setAccessible(true); + + DEBUG_NAME = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("debugName"); + DEBUG_NAME.setAccessible(true); + + REF_FIELD = Reference.class.getDeclaredField("referent"); + REF_FIELD.setAccessible(true); } catch (Exception ex) { throw new Error("Unexpected exception: ", ex); } @@ -138,6 +145,10 @@ public abstract class LambdaFormTestCase { testCase.getTestMethod().name); testCase.doTest(); System.err.println("PASSED"); + } catch (OutOfMemoryError e) { + // Don't swallow OOME so a heap dump can be created. + System.err.println("FAILED"); + throw e; } catch (Throwable t) { t.printStackTrace(); System.err.printf("FAILED. Caused by %s%n", t.getMessage()); From 06e81aae837e95df22bbe4c784d0b422ef716975 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 13 Jan 2015 17:14:51 +0000 Subject: [PATCH 36/72] 8068599: Add mutability, serializability, and thread-safety, caveat to all Collectors that do not accept a Collection supplier Reviewed-by: psandoz --- .../classes/java/util/stream/Collectors.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java index 6f68322119d..13321c0c932 100644 --- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java +++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java @@ -990,7 +990,7 @@ public final class Collectors { * function. * *

There are no guarantees on the type, mutability, or serializability - * of the {@code Map} or {@code List} objects returned, or of the + * of the {@code ConcurrentMap} or {@code List} objects returned, or of the * thread-safety of the {@code List} objects returned. * @implSpec * This produces a result similar to: @@ -1028,6 +1028,9 @@ public final class Collectors { * produces a result of type {@code D}. The resulting collector produces a * {@code Map}. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * *

For example, to compute the set of last names of people in each city, * where the city names are sorted: *

{@code
@@ -1143,7 +1146,8 @@ public final class Collectors {
      * {@code Map>}.
      *
      * There are no guarantees on the type, mutability,
-     * serializability, or thread-safety of the {@code Map} returned.
+     * serializability, or thread-safety of the {@code Map} or {@code List}
+     * returned.
      *
      * @param  the type of the input elements
      * @param predicate a predicate used for classifying input elements
@@ -1212,6 +1216,9 @@ public final class Collectors {
      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
      * instead.
      *
+     * 

There are no guarantees on the type, mutability, serializability, + * or thread-safety of the {@code Map} returned. + * * @apiNote * It is common for either the key or the value to be the input elements. * In this case, the utility method @@ -1271,6 +1278,9 @@ public final class Collectors { * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * + *

There are no guarantees on the type, mutability, serializability, + * or thread-safety of the {@code Map} returned. + * * @apiNote * There are multiple ways to deal with collisions between multiple elements * mapping to the same key. The other forms of {@code toMap} simply use @@ -1382,6 +1392,9 @@ public final class Collectors { * may have duplicates, use * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * * @apiNote * It is common for either the key or the value to be the input elements. * In this case, the utility method @@ -1436,6 +1449,9 @@ public final class Collectors { * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * * @apiNote * There are multiple ways to deal with collisions between multiple elements * mapping to the same key. The other forms of {@code toConcurrentMap} simply use From 3793aceccebbc1fd931aba6885e18d6a165a613d Mon Sep 17 00:00:00 2001 From: Jason Uh Date: Tue, 13 Jan 2015 14:33:54 -0800 Subject: [PATCH 37/72] 8059916: Change default criticality of policy mappings and policy constraints certificate extensions Reviewed-by: mullan --- .../x509/PolicyConstraintsExtension.java | 8 ++- .../x509/PolicyMappingsExtension.java | 10 ++-- .../x509/Extensions/DefaultCriticality.java | 50 +++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 jdk/test/sun/security/x509/Extensions/DefaultCriticality.java diff --git a/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java b/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java index ce10b3e6645..3b0543b202f 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,7 @@ package sun.security.x509; import java.io.IOException; import java.io.OutputStream; -import java.security.cert.CertificateException; import java.util.Enumeration; -import java.util.Vector; import sun.security.util.*; @@ -111,7 +109,7 @@ implements CertAttrSet { */ public PolicyConstraintsExtension(int require, int inhibit) throws IOException { - this(Boolean.FALSE, require, inhibit); + this(Boolean.TRUE, require, inhibit); } /** @@ -202,7 +200,7 @@ implements CertAttrSet { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyConstraints_Id; - critical = false; + critical = true; encodeThis(); } super.encode(tmp); diff --git a/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java b/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java index fba510469f5..d37bafccc1d 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,7 @@ implements CertAttrSet { throws IOException { this.maps = map; this.extensionId = PKIXExtensions.PolicyMappings_Id; - this.critical = false; + this.critical = true; encodeThis(); } @@ -100,8 +100,8 @@ implements CertAttrSet { * Create a default PolicyMappingsExtension. */ public PolicyMappingsExtension() { - extensionId = PKIXExtensions.KeyUsage_Id; - critical = false; + extensionId = PKIXExtensions.PolicyMappings_Id; + critical = true; maps = new ArrayList(); } @@ -153,7 +153,7 @@ implements CertAttrSet { DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyMappings_Id; - critical = false; + critical = true; encodeThis(); } super.encode(tmp); diff --git a/jdk/test/sun/security/x509/Extensions/DefaultCriticality.java b/jdk/test/sun/security/x509/Extensions/DefaultCriticality.java new file mode 100644 index 00000000000..102109a6021 --- /dev/null +++ b/jdk/test/sun/security/x509/Extensions/DefaultCriticality.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Change default criticality of policy mappings and policy constraints + certificate extensions + * @bug 8059916 + */ + +import sun.security.x509.PolicyConstraintsExtension; +import sun.security.x509.PolicyMappingsExtension; + +public class DefaultCriticality { + public static void main(String [] args) throws Exception { + PolicyConstraintsExtension pce = new PolicyConstraintsExtension(-1,-1); + if (!pce.isCritical()) { + throw new Exception("PolicyConstraintsExtension should be " + + "critical by default"); + } + + PolicyMappingsExtension pme = new PolicyMappingsExtension(); + if (!pme.isCritical()) { + throw new Exception("PolicyMappingsExtension should be " + + "critical by default"); + } + + System.out.println("Test passed."); + } +} From f080b654f50c51f18836f5145d538b14ac05aa99 Mon Sep 17 00:00:00 2001 From: Srinivasan Raghavan Date: Wed, 14 Jan 2015 13:43:12 +0300 Subject: [PATCH 38/72] 8058793: Test sun/awt/datatransfer/DataFlavorComparatorTest.java fails with compilation error Reviewed-by: alexsch, azvegint --- jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java index 9ef6eab2306..18ff2fc14ab 100644 --- a/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java +++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java @@ -29,13 +29,14 @@ */ import sun.awt.datatransfer.DataTransferer; - +import java.util.Comparator; +import sun.datatransfer.DataFlavorUtil; import java.awt.datatransfer.DataFlavor; public class DataFlavorComparatorTest { public static void main(String[] args) { - DataTransferer.DataFlavorComparator comparator = new DataTransferer.DataFlavorComparator(); + Comparator comparator = DataFlavorUtil.getDataFlavorComparator(); DataFlavor flavor1 = DataFlavor.imageFlavor; DataFlavor flavor2 = DataFlavor.selectionHtmlFlavor; if (comparator.compare(flavor1, flavor2) == 0) { From 3a90ffa2ab4dcb2f8b08b47c765d6c9bed859317 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Tue, 6 Jan 2015 06:49:52 +0100 Subject: [PATCH 39/72] 8068498: Remove constructor dependency on line.separator from PrintWriter and BufferedWriter Reviewed-by: alanb, sherman --- .../share/classes/java/io/BufferedWriter.java | 13 ++----------- .../share/classes/java/io/PrintWriter.java | 12 ++---------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/io/BufferedWriter.java b/jdk/src/java.base/share/classes/java/io/BufferedWriter.java index be4b6cd8539..5755499b9ff 100644 --- a/jdk/src/java.base/share/classes/java/io/BufferedWriter.java +++ b/jdk/src/java.base/share/classes/java/io/BufferedWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,12 +72,6 @@ public class BufferedWriter extends Writer { private static int defaultCharBufferSize = 8192; - /** - * Line separator string. This is the value of the line.separator - * property at the moment that the stream was created. - */ - private String lineSeparator; - /** * Creates a buffered character-output stream that uses a default-sized * output buffer. @@ -105,9 +99,6 @@ public class BufferedWriter extends Writer { cb = new char[sz]; nChars = sz; nextChar = 0; - - lineSeparator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("line.separator")); } /** Checks to make sure that the stream has not been closed */ @@ -240,7 +231,7 @@ public class BufferedWriter extends Writer { * @exception IOException If an I/O error occurs */ public void newLine() throws IOException { - write(lineSeparator); + write(System.lineSeparator()); } /** diff --git a/jdk/src/java.base/share/classes/java/io/PrintWriter.java b/jdk/src/java.base/share/classes/java/io/PrintWriter.java index c56c1bd8b91..03f4ef67e2f 100644 --- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,12 +68,6 @@ public class PrintWriter extends Writer { private Formatter formatter; private PrintStream psOut = null; - /** - * Line separator string. This is the value of the line.separator - * property at the moment that the stream was created. - */ - private final String lineSeparator; - /** * Returns a charset object for the given charset name. * @throws NullPointerException is csn is null @@ -113,8 +107,6 @@ public class PrintWriter extends Writer { super(out); this.out = out; this.autoFlush = autoFlush; - lineSeparator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("line.separator")); } /** @@ -477,7 +469,7 @@ public class PrintWriter extends Writer { try { synchronized (lock) { ensureOpen(); - out.write(lineSeparator); + out.write(System.lineSeparator()); if (autoFlush) out.flush(); } From 27a1ed85b6199a0e4897ff529fa3160b459f74ee Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 6 Jan 2015 19:30:28 -0500 Subject: [PATCH 40/72] 8067836: The Universe::flush_foo methods belong in CodeCache Move this code to CodeCache. Reviewed-by: kbarrett, kvn --- .../share/vm/classfile/systemDictionary.cpp | 5 +- hotspot/src/share/vm/code/codeCache.cpp | 113 +++++++++++++++++- hotspot/src/share/vm/code/codeCache.hpp | 14 ++- hotspot/src/share/vm/memory/universe.cpp | 113 ------------------ hotspot/src/share/vm/memory/universe.hpp | 10 -- hotspot/src/share/vm/oops/method.cpp | 5 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 4 +- hotspot/src/share/vm/prims/methodHandles.cpp | 7 +- 8 files changed, 137 insertions(+), 134 deletions(-) diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 9940f8e34e1..3e2589ef3c5 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/interpreter.hpp" @@ -1627,7 +1628,7 @@ void SystemDictionary::add_to_hierarchy(instanceKlassHandle k, TRAPS) { // Note: must be done *after* linking k into the hierarchy (was bug 12/9/97) // Also, first reinitialize vtable because it may have gotten out of synch // while the new class wasn't connected to the class hierarchy. - Universe::flush_dependents_on(k); + CodeCache::flush_dependents_on(k); } // ---------------------------------------------------------------------------- diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index f81e2983172..af50207fbbf 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1005,6 +1005,117 @@ void CodeCache::make_marked_nmethods_not_entrant() { } } +// Flushes compiled methods dependent on dependee. +void CodeCache::flush_dependents_on(instanceKlassHandle dependee) { + assert_lock_strong(Compile_lock); + + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + KlassDepChange changes(dependee); + + // Compute the dependent nmethods + if (mark_for_deoptimization(changes) > 0) { + // At least one nmethod has been marked for deoptimization + VM_Deoptimize op; + VMThread::execute(&op); + } +} + +// Flushes compiled methods dependent on a particular CallSite +// instance when its target is different than the given MethodHandle. +void CodeCache::flush_dependents_on(Handle call_site, Handle method_handle) { + assert_lock_strong(Compile_lock); + + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + CallSiteDepChange changes(call_site(), method_handle()); + + // Compute the dependent nmethods that have a reference to a + // CallSite object. We use InstanceKlass::mark_dependent_nmethod + // directly instead of CodeCache::mark_for_deoptimization because we + // want dependents on the call site class only not all classes in + // the ContextStream. + int marked = 0; + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass()); + marked = call_site_klass->mark_dependent_nmethods(changes); + } + if (marked > 0) { + // At least one nmethod has been marked for deoptimization + VM_Deoptimize op; + VMThread::execute(&op); + } +} + +#ifdef HOTSWAP +// Flushes compiled methods dependent on dependee in the evolutionary sense +void CodeCache::flush_evol_dependents_on(instanceKlassHandle ev_k_h) { + // --- Compile_lock is not held. However we are at a safepoint. + assert_locked_or_safepoint(Compile_lock); + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + // Compute the dependent nmethods + if (mark_for_evol_deoptimization(ev_k_h) > 0) { + // At least one nmethod has been marked for deoptimization + + // All this already happens inside a VM_Operation, so we'll do all the work here. + // Stuff copied from VM_Deoptimize and modified slightly. + + // We do not want any GCs to happen while we are in the middle of this VM operation + ResourceMark rm; + DeoptimizationMarker dm; + + // Deoptimize all activations depending on marked nmethods + Deoptimization::deoptimize_dependents(); + + // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) + make_marked_nmethods_not_entrant(); + } +} +#endif // HOTSWAP + + +// Flushes compiled methods dependent on dependee +void CodeCache::flush_dependents_on_method(methodHandle m_h) { + // --- Compile_lock is not held. However we are at a safepoint. + assert_locked_or_safepoint(Compile_lock); + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped dring the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + // Compute the dependent nmethods + if (mark_for_deoptimization(m_h()) > 0) { + // At least one nmethod has been marked for deoptimization + + // All this already happens inside a VM_Operation, so we'll do all the work here. + // Stuff copied from VM_Deoptimize and modified slightly. + + // We do not want any GCs to happen while we are in the middle of this VM operation + ResourceMark rm; + DeoptimizationMarker dm; + + // Deoptimize all activations depending on marked nmethods + Deoptimization::deoptimize_dependents(); + + // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) + make_marked_nmethods_not_entrant(); + } +} + void CodeCache::verify() { assert_locked_or_safepoint(CodeCache_lock); FOR_ALL_HEAPS(heap) { diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp index 25c5288cdde..287c531a4de 100644 --- a/hotspot/src/share/vm/code/codeCache.hpp +++ b/hotspot/src/share/vm/code/codeCache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,16 +209,28 @@ class CodeCache : AllStatic { static void verify_icholder_relocations(); // Deoptimization + private: static int mark_for_deoptimization(DepChange& changes); #ifdef HOTSWAP static int mark_for_evol_deoptimization(instanceKlassHandle dependee); #endif // HOTSWAP + public: static void mark_all_nmethods_for_deoptimization(); static int mark_for_deoptimization(Method* dependee); static void make_marked_nmethods_zombies(); static void make_marked_nmethods_not_entrant(); + // Flushing and deoptimization + static void flush_dependents_on(instanceKlassHandle dependee); + static void flush_dependents_on(Handle call_site, Handle method_handle); +#ifdef HOTSWAP + // Flushing and deoptimization in case of evolution + static void flush_evol_dependents_on(instanceKlassHandle dependee); +#endif // HOTSWAP + // Support for fullspeed debugging + static void flush_dependents_on_method(methodHandle dependee); + // tells how many nmethods have dependencies static int number_of_nmethods_with_dependencies(); diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index fe33e7a156f..f536793d41a 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1074,119 +1074,6 @@ void Universe::compute_base_vtable_size() { } -// %%% The Universe::flush_foo methods belong in CodeCache. - -// Flushes compiled methods dependent on dependee. -void Universe::flush_dependents_on(instanceKlassHandle dependee) { - assert_lock_strong(Compile_lock); - - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - KlassDepChange changes(dependee); - - // Compute the dependent nmethods - if (CodeCache::mark_for_deoptimization(changes) > 0) { - // At least one nmethod has been marked for deoptimization - VM_Deoptimize op; - VMThread::execute(&op); - } -} - -// Flushes compiled methods dependent on a particular CallSite -// instance when its target is different than the given MethodHandle. -void Universe::flush_dependents_on(Handle call_site, Handle method_handle) { - assert_lock_strong(Compile_lock); - - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - CallSiteDepChange changes(call_site(), method_handle()); - - // Compute the dependent nmethods that have a reference to a - // CallSite object. We use InstanceKlass::mark_dependent_nmethod - // directly instead of CodeCache::mark_for_deoptimization because we - // want dependents on the call site class only not all classes in - // the ContextStream. - int marked = 0; - { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass()); - marked = call_site_klass->mark_dependent_nmethods(changes); - } - if (marked > 0) { - // At least one nmethod has been marked for deoptimization - VM_Deoptimize op; - VMThread::execute(&op); - } -} - -#ifdef HOTSWAP -// Flushes compiled methods dependent on dependee in the evolutionary sense -void Universe::flush_evol_dependents_on(instanceKlassHandle ev_k_h) { - // --- Compile_lock is not held. However we are at a safepoint. - assert_locked_or_safepoint(Compile_lock); - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - // Compute the dependent nmethods - if (CodeCache::mark_for_evol_deoptimization(ev_k_h) > 0) { - // At least one nmethod has been marked for deoptimization - - // All this already happens inside a VM_Operation, so we'll do all the work here. - // Stuff copied from VM_Deoptimize and modified slightly. - - // We do not want any GCs to happen while we are in the middle of this VM operation - ResourceMark rm; - DeoptimizationMarker dm; - - // Deoptimize all activations depending on marked nmethods - Deoptimization::deoptimize_dependents(); - - // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) - CodeCache::make_marked_nmethods_not_entrant(); - } -} -#endif // HOTSWAP - - -// Flushes compiled methods dependent on dependee -void Universe::flush_dependents_on_method(methodHandle m_h) { - // --- Compile_lock is not held. However we are at a safepoint. - assert_locked_or_safepoint(Compile_lock); - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped dring the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - // Compute the dependent nmethods - if (CodeCache::mark_for_deoptimization(m_h()) > 0) { - // At least one nmethod has been marked for deoptimization - - // All this already happens inside a VM_Operation, so we'll do all the work here. - // Stuff copied from VM_Deoptimize and modified slightly. - - // We do not want any GCs to happen while we are in the middle of this VM operation - ResourceMark rm; - DeoptimizationMarker dm; - - // Deoptimize all activations depending on marked nmethods - Deoptimization::deoptimize_dependents(); - - // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) - CodeCache::make_marked_nmethods_not_entrant(); - } -} - void Universe::print() { print_on(gclog_or_tty); } diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index 2235cd1c876..0861fba3f0e 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -484,16 +484,6 @@ class Universe: AllStatic { static uintptr_t verify_mark_bits() PRODUCT_RETURN0; static uintptr_t verify_mark_mask() PRODUCT_RETURN0; - // Flushing and deoptimization - static void flush_dependents_on(instanceKlassHandle dependee); - static void flush_dependents_on(Handle call_site, Handle method_handle); -#ifdef HOTSWAP - // Flushing and deoptimization in case of evolution - static void flush_evol_dependents_on(instanceKlassHandle dependee); -#endif // HOTSWAP - // Support for fullspeed debugging - static void flush_dependents_on_method(methodHandle dependee); - // Compiler support static int base_vtable_size() { return _base_vtable_size; } }; diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 054479986c7..62a1501ab95 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/metadataOnStackMark.hpp" #include "classfile/systemDictionary.hpp" +#include "code/codeCache.hpp" #include "code/debugInfoRec.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "interpreter/bytecodeStream.hpp" @@ -1727,7 +1728,7 @@ void BreakpointInfo::set(Method* method) { // Deoptimize all dependents on this method HandleMark hm(thread); methodHandle mh(thread, method); - Universe::flush_dependents_on_method(mh); + CodeCache::flush_dependents_on_method(mh); } } diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index a4c76771028..7da07a3875b 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3766,7 +3766,7 @@ void VM_RedefineClasses::flush_dependent_code(instanceKlassHandle k_h, TRAPS) { // All dependencies have been recorded from startup or this is a second or // subsequent use of RedefineClasses if (JvmtiExport::all_dependencies_are_recorded()) { - Universe::flush_evol_dependents_on(k_h); + CodeCache::flush_evol_dependents_on(k_h); } else { CodeCache::mark_all_nmethods_for_deoptimization(); diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index 82e15cababb..d036e1d2c27 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/stringTable.hpp" +#include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/oopMapCache.hpp" @@ -1245,7 +1246,7 @@ JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject { // Walk all nmethods depending on this call site. MutexLocker mu(Compile_lock, thread); - Universe::flush_dependents_on(call_site, target); + CodeCache::flush_dependents_on(call_site, target); java_lang_invoke_CallSite::set_target(call_site(), target()); } } @@ -1257,7 +1258,7 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec { // Walk all nmethods depending on this call site. MutexLocker mu(Compile_lock, thread); - Universe::flush_dependents_on(call_site, target); + CodeCache::flush_dependents_on(call_site, target); java_lang_invoke_CallSite::set_target_volatile(call_site(), target()); } } From 16f26a80d62309c332427bfecf3359a4c49408af Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 7 Jan 2015 10:17:45 +0100 Subject: [PATCH 41/72] 8067676: Add applicable closed gc jtreg tests to run in JPRT Reviewed-by: ehelin --- make/jprt.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/make/jprt.properties b/make/jprt.properties index d9cd1498649..805b597d77f 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -486,6 +486,7 @@ my.make.rule.test.targets.hotspot= \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler_3}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc}, \ + ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_serviceability}, \ From 5203f2c751e6a54dee4c8023a96f762eff57c20c Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 7 Jan 2015 10:19:00 +0100 Subject: [PATCH 42/72] 8067676: Add applicable closed gc jtreg tests to run in JPRT Reviewed-by: ehelin --- hotspot/test/TEST.groups | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 261e0cf073c..20606449fbe 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -413,6 +413,9 @@ hotspot_gc = \ gc/ \ -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java +hotspot_gc_closed = \ + sanity/ExecuteInternalVMTests.java + hotspot_runtime = \ runtime/ \ -runtime/6888954/vmerrors.sh \ @@ -444,6 +447,7 @@ hotspot_jprt = \ :hotspot_compiler_3 \ :hotspot_compiler_closed \ :hotspot_gc \ + :hotspot_gc_closed \ :hotspot_runtime \ :hotspot_runtime_closed \ :hotspot_serviceability From b8f42f53dad21ba291b4060e85c694c086e7cd66 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 7 Jan 2015 15:02:00 +0100 Subject: [PATCH 43/72] 8067868: Add GCOld as a JTreg test Reviewed-by: kbarrett, dfazunen, ehelin --- hotspot/test/TEST.groups | 4 + hotspot/test/stress/gc/TestGCOld.java | 417 ++++++++++++++++++++++++++ 2 files changed, 421 insertions(+) create mode 100644 hotspot/test/stress/gc/TestGCOld.java diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index 20606449fbe..4baaecef4de 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -416,6 +416,9 @@ hotspot_gc = \ hotspot_gc_closed = \ sanity/ExecuteInternalVMTests.java +hotspot_gc_gcold = \ + stress/gc/TestGCOld.java + hotspot_runtime = \ runtime/ \ -runtime/6888954/vmerrors.sh \ @@ -448,6 +451,7 @@ hotspot_jprt = \ :hotspot_compiler_closed \ :hotspot_gc \ :hotspot_gc_closed \ + :hotspot_gc_gcold \ :hotspot_runtime \ :hotspot_runtime_closed \ :hotspot_serviceability diff --git a/hotspot/test/stress/gc/TestGCOld.java b/hotspot/test/stress/gc/TestGCOld.java new file mode 100644 index 00000000000..336cb09cca5 --- /dev/null +++ b/hotspot/test/stress/gc/TestGCOld.java @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* + * @test TestGCOld + * @key gc + * @key stress + * @requires vm.gc=="null" + * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects. + * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000 + */ + +import java.text.*; +import java.util.Random; + +class TreeNode { + public TreeNode left, right; + public int val; // will always be the height of the tree +} + + +/* Args: + live-data-size: in megabytes (approximate, will be rounded down). + work: units of mutator non-allocation work per byte allocated, + (in unspecified units. This will affect the promotion rate + printed at the end of the run: more mutator work per step implies + fewer steps per second implies fewer bytes promoted per second.) + short/long ratio: ratio of short-lived bytes allocated to long-lived + bytes allocated. + pointer mutation rate: number of pointer mutations per step. + steps: number of steps to do. +*/ + +public class TestGCOld { + + // Command-line parameters. + + private static int size, workUnits, promoteRate, ptrMutRate, steps; + + // Constants. + + private static final int MEG = 1000000; + private static final int INSIGNIFICANT = 999; // this many bytes don't matter + private static final int BYTES_PER_WORD = 4; + private static final int BYTES_PER_NODE = 20; // bytes per TreeNode + private static final int WORDS_DEAD = 100; // size of young garbage object + + private final static int treeHeight = 14; + private final static long treeSize = heightToBytes(treeHeight); + + private static final String msg1 + = "Usage: java TestGCOld "; + private static final String msg2 + = " where is the live storage in megabytes"; + private static final String msg3 + = " is the mutator work per step (arbitrary units)"; + private static final String msg4 + = " is the ratio of short-lived to long-lived allocation"; + private static final String msg5 + = " is the mutations per step"; + private static final String msg6 + = " is the number of steps"; + + // Counters (and global variables that discourage optimization) + + private static long youngBytes = 0; // total young bytes allocated + private static long nodes = 0; // total tree nodes allocated + private static long actuallyMut = 0; // pointer mutations in old trees + private static long mutatorSum = 0; // checksum to discourage optimization + public static int[] aexport; // exported array to discourage opt + + // Global variables. + + private static TreeNode[] trees; + private static int where = 0; // roving index into trees + private static Random rnd = new Random(); + + // Returns the height of the given tree. + + private static int height (TreeNode t) { + if (t == null) { + return 0; + } + else { + return 1 + Math.max (height (t.left), height (t.right)); + } + } + + // Returns the length of the shortest path in the given tree. + + private static int shortestPath (TreeNode t) { + if (t == null) { + return 0; + } + else { + return 1 + Math.min (shortestPath (t.left), shortestPath (t.right)); + } + } + + // Returns the number of nodes in a balanced tree of the given height. + + private static long heightToNodes (int h) { + if (h == 0) { + return 0; + } + else { + long n = 1; + while (h > 1) { + n = n + n; + h = h - 1; + } + return n + n - 1; + } + } + + // Returns the number of bytes in a balanced tree of the given height. + + private static long heightToBytes (int h) { + return BYTES_PER_NODE * heightToNodes (h); + } + + // Returns the height of the largest balanced tree + // that has no more than the given number of nodes. + + private static int nodesToHeight (long nodes) { + int h = 1; + long n = 1; + while (n + n - 1 <= nodes) { + n = n + n; + h = h + 1; + } + return h - 1; + } + + // Returns the height of the largest balanced tree + // that occupies no more than the given number of bytes. + + private static int bytesToHeight (long bytes) { + return nodesToHeight (bytes / BYTES_PER_NODE); + } + + // Returns a newly allocated balanced binary tree of height h. + + private static TreeNode makeTree(int h) { + if (h == 0) return null; + else { + TreeNode res = new TreeNode(); + nodes++; + res.left = makeTree(h-1); + res.right = makeTree(h-1); + res.val = h; + return res; + } + } + + // Allocates approximately size megabytes of trees and stores + // them into a global array. + + private static void init() { + int ntrees = (int) ((size * MEG) / treeSize); + trees = new TreeNode[ntrees]; + + System.err.println("Allocating " + ntrees + " trees."); + System.err.println(" (" + (ntrees * treeSize) + " bytes)"); + for (int i = 0; i < ntrees; i++) { + trees[i] = makeTree(treeHeight); + // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD); + } + System.err.println(" (" + nodes + " nodes)"); + + /* Allow any in-progress GC to catch up... */ + // try { Thread.sleep(20000); } catch (InterruptedException x) {} + } + + // Confirms that all trees are balanced and have the correct height. + + private static void checkTrees() { + int ntrees = trees.length; + for (int i = 0; i < ntrees; i++) { + TreeNode t = trees[i]; + int h1 = height(t); + int h2 = shortestPath(t); + if ((h1 != treeHeight) || (h2 != treeHeight)) { + System.err.println("*****BUG: " + h1 + " " + h2); + } + } + } + + // Called only by replaceTree (below) and by itself. + + private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) { + boolean canGoLeft = full.left != null && full.left.val > partial.val; + boolean canGoRight = full.right != null && full.right.val > partial.val; + if (canGoLeft && canGoRight) { + if (dir) + replaceTreeWork(full.left, partial, !dir); + else + replaceTreeWork(full.right, partial, !dir); + } else if (!canGoLeft && !canGoRight) { + if (dir) + full.left = partial; + else + full.right = partial; + } else if (!canGoLeft) { + full.left = partial; + } else { + full.right = partial; + } + } + + // Given a balanced tree full and a smaller balanced tree partial, + // replaces an appropriate subtree of full by partial, taking care + // to preserve the shape of the full tree. + + private static void replaceTree(TreeNode full, TreeNode partial) { + boolean dir = (partial.val % 2) == 0; + actuallyMut++; + replaceTreeWork(full, partial, dir); + } + + // Allocates approximately n bytes of long-lived storage, + // replacing oldest existing long-lived storage. + + private static void oldGenAlloc(long n) { + int full = (int) (n / treeSize); + long partial = n % treeSize; + // System.out.println("In oldGenAlloc, doing " + full + " full trees " + // + "and one partial tree of size " + partial); + for (int i = 0; i < full; i++) { + trees[where++] = makeTree(treeHeight); + if (where == trees.length) where = 0; + } + while (partial > INSIGNIFICANT) { + int h = bytesToHeight(partial); + TreeNode newTree = makeTree(h); + replaceTree(trees[where++], newTree); + if (where == trees.length) where = 0; + partial = partial - heightToBytes(h); + } + } + + // Interchanges two randomly selected subtrees (of same size and depth). + + private static void oldGenSwapSubtrees() { + // Randomly pick: + // * two tree indices + // * A depth + // * A path to that depth. + int index1 = rnd.nextInt(trees.length); + int index2 = rnd.nextInt(trees.length); + int depth = rnd.nextInt(treeHeight); + int path = rnd.nextInt(); + TreeNode tn1 = trees[index1]; + TreeNode tn2 = trees[index2]; + for (int i = 0; i < depth; i++) { + if ((path & 1) == 0) { + tn1 = tn1.left; + tn2 = tn2.left; + } else { + tn1 = tn1.right; + tn2 = tn2.right; + } + path >>= 1; + } + TreeNode tmp; + if ((path & 1) == 0) { + tmp = tn1.left; + tn1.left = tn2.left; + tn2.left = tmp; + } else { + tmp = tn1.right; + tn1.right = tn2.right; + tn2.right = tmp; + } + actuallyMut += 2; + } + + // Update "n" old-generation pointers. + + private static void oldGenMut(long n) { + for (int i = 0; i < n/2; i++) { + oldGenSwapSubtrees(); + } + } + + // Does the amount of mutator work appropriate for n bytes of young-gen + // garbage allocation. + + private static void doMutWork(long n) { + int sum = 0; + long limit = workUnits*n/10; + for (long k = 0; k < limit; k++) sum++; + // We don't want dead code elimination to eliminate the loop above. + mutatorSum = mutatorSum + sum; + } + + // Allocate n bytes of young-gen garbage, in units of "nwords" + // words. + + private static void doYoungGenAlloc(long n, int nwords) { + final int nbytes = nwords*BYTES_PER_WORD; + int allocated = 0; + while (allocated < n) { + aexport = new int[nwords]; + /* System.err.println("Step"); */ + allocated += nbytes; + } + youngBytes = youngBytes + allocated; + } + + // Allocate "n" bytes of young-gen data; and do the + // corresponding amount of old-gen allocation and pointer + // mutation. + + // oldGenAlloc may perform some mutations, so this code + // takes those mutations into account. + + private static void doStep(long n) { + long mutations = actuallyMut; + + doYoungGenAlloc(n, WORDS_DEAD); + doMutWork(n); + oldGenAlloc(n / promoteRate); + oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut)); + } + + public static void main(String[] args) { + if (args.length != 5) { + System.err.println(msg1); + System.err.println(msg2); + System.err.println(msg3); + System.err.println(msg4); + System.err.println(msg5); + System.err.println(msg6); + return; + } + + size = Integer.parseInt(args[0]); + workUnits = Integer.parseInt(args[1]); + promoteRate = Integer.parseInt(args[2]); + ptrMutRate = Integer.parseInt(args[3]); + steps = Integer.parseInt(args[4]); + + System.out.println(size + " megabytes of live storage"); + System.out.println(workUnits + " work units per step"); + System.out.println("promotion ratio is 1:" + promoteRate); + System.out.println("pointer mutation rate is " + ptrMutRate); + System.out.println(steps + " steps"); + + init(); +// checkTrees(); + youngBytes = 0; + nodes = 0; + + System.err.println("Initialization complete..."); + + long start = System.currentTimeMillis(); + + for (int step = 0; step < steps; step++) { + doStep(MEG); + } + + long end = System.currentTimeMillis(); + float secs = ((float)(end-start))/1000.0F; + +// checkTrees(); + + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(1); + System.out.println("\nTook " + nf.format(secs) + " sec in steady state."); + nf.setMaximumFractionDigits(2); + System.out.println("Allocated " + steps + " Mb of young gen garbage" + + " (= " + nf.format(((float)steps)/secs) + + " Mb/sec)"); + System.out.println(" (actually allocated " + + nf.format(((float) youngBytes)/MEG) + " megabytes)"); + float promoted = ((float)steps) / (float)promoteRate; + System.out.println("Promoted " + promoted + + " Mb (= " + nf.format(promoted/secs) + " Mb/sec)"); + System.out.println(" (actually promoted " + + nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) + + " megabytes)"); + if (ptrMutRate != 0) { + System.out.println("Mutated " + actuallyMut + + " pointers (= " + + nf.format(actuallyMut/secs) + " ptrs/sec)"); + + } + // This output serves mainly to discourage optimization. + System.out.println("Checksum = " + (mutatorSum + aexport.length)); + + } +} From f96d05132da703dd96c221b855e66a72cdcc7cb9 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 7 Jan 2015 15:02:33 +0100 Subject: [PATCH 44/72] 8067868: Add GCOld as a JTreg test Reviewed-by: kbarrett, dfazunen, ehelin --- make/jprt.properties | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/make/jprt.properties b/make/jprt.properties index 805b597d77f..036a64e6ca2 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -269,11 +269,6 @@ my.test.targets.hotspot.solaris.sparcv9= \ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_CMS, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_G1, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_SerialGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_ParallelGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_ParOldGC, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_default_nontiered, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_SerialGC, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_ParallelGC, \ @@ -293,17 +288,9 @@ my.test.targets.hotspot.solaris.x64= \ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_CMS, \ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_G1, \ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_SerialGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParallelGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParOldGC, \ solaris_x64_5.11-{product|fastdebug}-c2-jbb_default_nontiered, \ solaris_x64_5.11-{product|fastdebug}-c2-jbb_SerialGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-jbb_ParallelGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParOldGC + solaris_x64_5.11-{product|fastdebug}-c2-jbb_ParallelGC, my.test.targets.hotspot.linux.i586= \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-jvm98, \ @@ -319,11 +306,6 @@ my.test.targets.hotspot.linux.i586= \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_SerialGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_ParallelGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_CMS, \ - linux_i586_2.6-product-{c1|c2}-GCOld_G1, \ - linux_i586_2.6-product-{c1|c2}-GCOld_ParOldGC, \ linux_i586_2.6-{product|fastdebug}-c1-jbb_SerialGC, \ linux_i586_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \ linux_i586_2.6-{product|fastdebug}-c1-jbb_ParallelGC, \ @@ -340,11 +322,6 @@ my.test.targets.hotspot.linux.x64= \ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_CMS, \ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_G1, \ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_SerialGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParallelGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_CMS, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_G1, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParOldGC, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_ParallelGC, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_G1, \ @@ -359,11 +336,6 @@ my.test.targets.hotspot.macosx.x64= \ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_CMS, \ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_G1, \ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_SerialGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParallelGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_CMS, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_G1, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParOldGC, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_default_nontiered, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_ParallelGC, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_G1, \ @@ -382,11 +354,6 @@ my.test.targets.hotspot.windows.i586= \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_SerialGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_ParallelGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_CMS, \ - windows_i586_6.1-product-{c1|c2}-GCOld_G1, \ - windows_i586_6.1-product-{c1|c2}-GCOld_ParOldGC, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-jbb_default, \ windows_i586_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \ windows_i586_6.1-product-{c1|c2}-jbb_ParallelGC, \ @@ -406,11 +373,6 @@ my.test.targets.hotspot.windows.x64= \ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_CMS, \ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_G1, \ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_SerialGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParallelGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_CMS, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_G1, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParOldGC, \ windows_x64_6.1-{product|fastdebug}-c2-jbb_default, \ windows_x64_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \ windows_x64_6.1-product-c2-jbb_CMS, \ @@ -487,6 +449,7 @@ my.make.rule.test.targets.hotspot= \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc_closed}, \ + ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc_gcold}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_serviceability}, \ From afb458ef0ec0720c770d6431951d30f671741450 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 7 Jan 2015 15:15:37 +0100 Subject: [PATCH 45/72] 8048179: Early reclaim of large objects that are referenced by a few objects Push the remembered sets of large objects with few referenced into the dirty card queue at the beginning of the evacuation so that they may end up with zero remembered set entries at the end of the collection, and are potentially reclaimed. Also improve timing measurements of the early reclaim mechanism, and shorten flag names. Reviewed-by: brutisso, jmasa, dfazunen --- .../gc_implementation/g1/g1CollectedHeap.cpp | 92 ++++++++++---- .../gc_implementation/g1/g1CollectedHeap.hpp | 3 + .../gc_implementation/g1/g1GCPhaseTimes.cpp | 7 +- .../gc_implementation/g1/g1GCPhaseTimes.hpp | 4 +- .../vm/gc_implementation/g1/g1_globals.hpp | 8 +- .../gc_implementation/g1/heapRegionRemSet.cpp | 12 ++ .../gc_implementation/g1/heapRegionRemSet.hpp | 8 ++ ...ReclaimHumongousRegionsClearMarkBits.java} | 4 +- ...tEagerReclaimHumongousRegionsWithRefs.java | 113 ++++++++++++++++++ ...tG1TraceEagerReclaimHumongousObjects.java} | 16 +-- hotspot/test/gc/g1/TestGCLogMessages.java | 9 +- 11 files changed, 232 insertions(+), 44 deletions(-) rename hotspot/test/gc/g1/{TestEagerReclaimHumongousRegions2.java => TestEagerReclaimHumongousRegionsClearMarkBits.java} (97%) create mode 100644 hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java rename hotspot/test/gc/g1/{TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java => TestG1TraceEagerReclaimHumongousObjects.java} (89%) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index b889a3622ec..335ba2265d5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2068,7 +2068,7 @@ void G1CollectedHeap::stop() { } void G1CollectedHeap::clear_humongous_is_live_table() { - guarantee(G1ReclaimDeadHumongousObjectsAtYoungGC, "Should only be called if true"); + guarantee(G1EagerReclaimHumongousObjects, "Should only be called if true"); _humongous_is_live.clear(); } @@ -3485,8 +3485,24 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure { private: size_t _total_humongous; size_t _candidate_humongous; + + DirtyCardQueue _dcq; + + bool humongous_region_is_candidate(uint index) { + HeapRegion* region = G1CollectedHeap::heap()->region_at(index); + assert(region->is_starts_humongous(), "Must start a humongous object"); + HeapRegionRemSet* const rset = region->rem_set(); + bool const allow_stale_refs = G1EagerReclaimHumongousObjectsWithStaleRefs; + return !oop(region->bottom())->is_objArray() && + ((allow_stale_refs && rset->occupancy_less_or_equal_than(G1RSetSparseRegionEntries)) || + (!allow_stale_refs && rset->is_empty())); + } + public: - RegisterHumongousWithInCSetFastTestClosure() : _total_humongous(0), _candidate_humongous(0) { + RegisterHumongousWithInCSetFastTestClosure() + : _total_humongous(0), + _candidate_humongous(0), + _dcq(&JavaThread::dirty_card_queue_set()) { } virtual bool doHeapRegion(HeapRegion* r) { @@ -3496,11 +3512,29 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure { G1CollectedHeap* g1h = G1CollectedHeap::heap(); uint region_idx = r->hrm_index(); - bool is_candidate = !g1h->humongous_region_is_always_live(region_idx); - // Is_candidate already filters out humongous regions with some remembered set. - // This will not lead to humongous object that we mistakenly keep alive because - // during young collection the remembered sets will only be added to. + bool is_candidate = humongous_region_is_candidate(region_idx); + // Is_candidate already filters out humongous object with large remembered sets. + // If we have a humongous object with a few remembered sets, we simply flush these + // remembered set entries into the DCQS. That will result in automatic + // re-evaluation of their remembered set entries during the following evacuation + // phase. if (is_candidate) { + if (!r->rem_set()->is_empty()) { + guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries), + "Found a not-small remembered set here. This is inconsistent with previous assumptions."); + G1SATBCardTableLoggingModRefBS* bs = g1h->g1_barrier_set(); + HeapRegionRemSetIterator hrrs(r->rem_set()); + size_t card_index; + while (hrrs.has_next(card_index)) { + jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index); + if (*card_ptr != CardTableModRefBS::dirty_card_val()) { + *card_ptr = CardTableModRefBS::dirty_card_val(); + _dcq.enqueue(card_ptr); + } + } + r->rem_set()->clear_locked(); + } + assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty."); g1h->register_humongous_region_with_in_cset_fast_test(region_idx); _candidate_humongous++; } @@ -3511,23 +3545,32 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure { size_t total_humongous() const { return _total_humongous; } size_t candidate_humongous() const { return _candidate_humongous; } + + void flush_rem_set_entries() { _dcq.flush(); } }; void G1CollectedHeap::register_humongous_regions_with_in_cset_fast_test() { - if (!G1ReclaimDeadHumongousObjectsAtYoungGC) { - g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0, 0); + if (!G1EagerReclaimHumongousObjects) { + g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0.0, 0, 0); return; } + double time = os::elapsed_counter(); RegisterHumongousWithInCSetFastTestClosure cl; heap_region_iterate(&cl); - g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(cl.total_humongous(), + + time = ((double)(os::elapsed_counter() - time) / os::elapsed_frequency()) * 1000.0; + g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(time, + cl.total_humongous(), cl.candidate_humongous()); _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0; - if (_has_humongous_reclaim_candidates || G1TraceReclaimDeadHumongousObjectsAtYoungGC) { + if (_has_humongous_reclaim_candidates || G1TraceEagerReclaimHumongousObjects) { clear_humongous_is_live_table(); } + + // Finally flush all remembered set entries to re-check into the global DCQS. + cl.flush_rem_set_entries(); } void @@ -6140,22 +6183,20 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure { // are completely up-to-date wrt to references to the humongous object. // // Other implementation considerations: - // - never consider object arrays: while they are a valid target, they have not - // been observed to be used as temporary objects. - // - they would also pose considerable effort for cleaning up the the remembered - // sets. - // While this cleanup is not strictly necessary to be done (or done instantly), - // given that their occurrence is very low, this saves us this additional - // complexity. + // - never consider object arrays at this time because they would pose + // considerable effort for cleaning up the the remembered sets. This is + // required because stale remembered sets might reference locations that + // are currently allocated into. uint region_idx = r->hrm_index(); if (g1h->humongous_is_live(region_idx) || g1h->humongous_region_is_always_live(region_idx)) { - if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) { - gclog_or_tty->print_cr("Live humongous %d region %d size "SIZE_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", - r->is_humongous(), + if (G1TraceEagerReclaimHumongousObjects) { + gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", region_idx, obj->size()*HeapWordSize, + r->bottom(), + r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), @@ -6171,12 +6212,11 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure { err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.", r->bottom())); - if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) { - gclog_or_tty->print_cr("Reclaim humongous region %d size "SIZE_FORMAT" start "PTR_FORMAT" region %d length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", - r->is_humongous(), + if (G1TraceEagerReclaimHumongousObjects) { + gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", + region_idx, obj->size()*HeapWordSize, r->bottom(), - region_idx, r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), @@ -6213,8 +6253,8 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure { void G1CollectedHeap::eagerly_reclaim_humongous_regions() { assert_at_safepoint(true); - if (!G1ReclaimDeadHumongousObjectsAtYoungGC || - (!_has_humongous_reclaim_candidates && !G1TraceReclaimDeadHumongousObjectsAtYoungGC)) { + if (!G1EagerReclaimHumongousObjects || + (!_has_humongous_reclaim_candidates && !G1TraceEagerReclaimHumongousObjects)) { g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms(0.0, 0); return; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 4b4878e33b8..ab79bcd05ad 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -641,6 +641,9 @@ public: // Returns whether the given region (which must be a humongous (start) region) // is to be considered conservatively live regardless of any other conditions. bool humongous_region_is_always_live(uint index); + // Returns whether the given region (which must be a humongous (start) region) + // is considered a candidate for eager reclamation. + bool humongous_region_is_candidate(uint index); // Register the given region to be part of the collection set. inline void register_humongous_region_with_in_cset_fast_test(uint index); // Register regions with humongous objects (actually on the start region) in diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp index 5db2c667390..f9e892b3bb2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp @@ -344,11 +344,14 @@ void G1GCPhaseTimes::print(double pause_time_sec) { _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty"); _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards"); } - if (G1ReclaimDeadHumongousObjectsAtYoungGC) { - print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); + if (G1EagerReclaimHumongousObjects) { + print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms); if (G1Log::finest()) { print_stats(3, "Humongous Total", _cur_fast_reclaim_humongous_total); print_stats(3, "Humongous Candidate", _cur_fast_reclaim_humongous_candidates); + } + print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); + if (G1Log::finest()) { print_stats(3, "Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp index 1a9cedda9bc..0c6c3312aa1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp @@ -157,6 +157,7 @@ class G1GCPhaseTimes : public CHeapObj { double _recorded_non_young_free_cset_time_ms; double _cur_fast_reclaim_humongous_time_ms; + double _cur_fast_reclaim_humongous_register_time_ms; size_t _cur_fast_reclaim_humongous_total; size_t _cur_fast_reclaim_humongous_candidates; size_t _cur_fast_reclaim_humongous_reclaimed; @@ -283,7 +284,8 @@ class G1GCPhaseTimes : public CHeapObj { _recorded_non_young_free_cset_time_ms = time_ms; } - void record_fast_reclaim_humongous_stats(size_t total, size_t candidates) { + void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) { + _cur_fast_reclaim_humongous_register_time_ms = time_ms; _cur_fast_reclaim_humongous_total = total; _cur_fast_reclaim_humongous_candidates = candidates; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index 1d8838740c1..303296812a7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -270,10 +270,14 @@ product(uintx, G1MixedGCCountTarget, 8, \ "The target number of mixed GCs after a marking cycle.") \ \ - experimental(bool, G1ReclaimDeadHumongousObjectsAtYoungGC, true, \ + experimental(bool, G1EagerReclaimHumongousObjects, true, \ "Try to reclaim dead large objects at every young GC.") \ \ - experimental(bool, G1TraceReclaimDeadHumongousObjectsAtYoungGC, false, \ + experimental(bool, G1EagerReclaimHumongousObjectsWithStaleRefs, true, \ + "Try to reclaim dead large objects that have a few stale " \ + "references at every young GC.") \ + \ + experimental(bool, G1TraceEagerReclaimHumongousObjects, false, \ "Print some information about large object liveness " \ "at every young GC.") \ \ diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 9551aed3022..f092f3ec9c2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -681,6 +681,18 @@ void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, clear_fcc(); } +bool OtherRegionsTable::occupancy_less_or_equal_than(size_t limit) const { + if (limit <= (size_t)G1RSetSparseRegionEntries) { + return occ_coarse() == 0 && _first_all_fine_prts == NULL && occ_sparse() <= limit; + } else { + // Current uses of this method may only use values less than G1RSetSparseRegionEntries + // for the limit. The solution, comparing against occupied() would be too slow + // at this time. + Unimplemented(); + return false; + } +} + bool OtherRegionsTable::is_empty() const { return occ_sparse() == 0 && occ_coarse() == 0 && _first_all_fine_prts == NULL; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp index bfff90abaef..adbee92d06a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp @@ -183,6 +183,10 @@ public: // Returns whether the remembered set contains the given reference. bool contains_reference(OopOrNarrowOopStar from) const; + // Returns whether this remembered set (and all sub-sets) have an occupancy + // that is less or equal than the given occupancy. + bool occupancy_less_or_equal_than(size_t limit) const; + // Removes any entries shown by the given bitmaps to contain only dead // objects. Not thread safe. // Set bits in the bitmaps indicate that the given region or card is live. @@ -261,6 +265,10 @@ public: return (strong_code_roots_list_length() == 0) && _other_regions.is_empty(); } + bool occupancy_less_or_equal_than(size_t occ) const { + return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ); + } + size_t occupied() { MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); return occupied_locked(); diff --git a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java similarity index 97% rename from hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java rename to hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java index dafbde0ed6f..5b4e694770f 100644 --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java @@ -22,7 +22,7 @@ */ /* - * @test TestEagerReclaimHumongousRegions2 + * @test TestEagerReclaimHumongousRegionsClearMarkBits * @bug 8051973 * @summary Test to make sure that eager reclaim of humongous objects correctly clears * mark bitmaps at reclaim. @@ -109,7 +109,7 @@ class ReclaimRegionFast { } } -public class TestEagerReclaimHumongousRegions2 { +public class TestEagerReclaimHumongousRegionsClearMarkBits { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UseG1GC", diff --git a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java new file mode 100644 index 00000000000..d12e25af720 --- /dev/null +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestEagerReclaimHumongousRegionsWithRefs + * @bug 8048179 + * @summary Test to make sure that eager reclaim of humongous objects that have previously + * been referenced by other old gen regions work. We simply try to fill + * up the heap with humongous objects and create a remembered set entry from an object by + * referencing that we know is in the old gen. After changing this reference, the object + * should still be eagerly reclaimable to avoid Full GC. + * @key gc + * @library /testlibrary + */ + +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.LinkedList; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import static com.oracle.java.testlibrary.Asserts.*; + +class RefHolder { + Object ref; +} + +class ReclaimRegionFast { + + public static final int M = 1024*1024; + + public static LinkedList garbageList = new LinkedList(); + + public static void genGarbage() { + for (int i = 0; i < 32*1024; i++) { + garbageList.add(new int[100]); + } + garbageList.clear(); + } + + + // A large object referenced by a static. + static int[] filler = new int[10 * M]; + + // Old gen object referencing the large object, generating remembered + // set entries. + static RefHolder fromOld = new RefHolder(); + + public static void main(String[] args) { + + int[] large = new int[M]; + + Object ref_from_stack = large; + + for (int i = 0; i < 100; i++) { + // A large object that will be reclaimed eagerly. + large = new int[6*M]; + fromOld.ref = large; + genGarbage(); + } + + // Keep the reference to the first object alive. + System.out.println(ref_from_stack); + } +} + +public class TestEagerReclaimHumongousRegionsWithRefs { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn16M", + "-XX:+PrintGC", + ReclaimRegionFast.class.getName()); + + Pattern p = Pattern.compile("Full GC"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + int found = 0; + Matcher m = p.matcher(output.getStdout()); + while (m.find()) { + found++; + } + System.out.println("Issued " + found + " Full GCs"); + + assertLessThan(found, 10, "Found that " + found + " Full GCs were issued. This is larger than the bound. Eager reclaim of objects once referenced from old gen seems to not work at all"); + output.shouldHaveExitValue(0); + } +} + diff --git a/hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java similarity index 89% rename from hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java rename to hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java index 67e60e03a6b..e653554c94e 100644 --- a/hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java +++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java @@ -22,9 +22,9 @@ */ /* - * @test TestG1TraceReclaimDeadHumongousObjectsAtYoungGC - * @bug 8058801 - * @summary Ensure that the output for a G1TraceReclaimDeadHumongousObjectsAtYoungGC + * @test TestG1TraceEagerReclaimHumongousObjects + * @bug 8058801 8048179 + * @summary Ensure that the output for a G1TraceEagerReclaimHumongousObjects * includes the expected necessary messages. * @key gc * @library /testlibrary @@ -34,7 +34,7 @@ import com.oracle.java.testlibrary.ProcessTools; import com.oracle.java.testlibrary.OutputAnalyzer; import java.util.LinkedList; -public class TestG1TraceReclaimDeadHumongousObjectsAtYoungGC { +public class TestG1TraceEagerReclaimHumongousObjects { public static void main(String[] args) throws Exception { testGCLogs(); testHumongousObjectGCLogs(); @@ -50,12 +50,12 @@ public class TestG1TraceReclaimDeadHumongousObjectsAtYoungGC { "-XX:+PrintGC", "-XX:+UnlockExperimentalVMOptions", "-XX:G1LogLevel=finest", - "-XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC", + "-XX:+G1TraceEagerReclaimHumongousObjects", GCTest.class.getName()); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed. + // As G1EagerReclaimHumongousObjects is set(default), below logs should be displayed. // And GCTest doesn't have humongous objects, so values should be zero. output.shouldContain("[Humongous Reclaim"); output.shouldContain("[Humongous Total: 0]"); @@ -74,7 +74,7 @@ public class TestG1TraceReclaimDeadHumongousObjectsAtYoungGC { "-XX:+PrintGC", "-XX:+UnlockExperimentalVMOptions", "-XX:G1LogLevel=finest", - "-XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC", + "-XX:+G1TraceEagerReclaimHumongousObjects", GCWithHumongousObjectTest.class.getName()); OutputAnalyzer output = new OutputAnalyzer(pb.start()); @@ -88,7 +88,7 @@ public class TestG1TraceReclaimDeadHumongousObjectsAtYoungGC { // As G1TraceReclaimDeadHumongousObjectsAtYoungGC is set and GCWithHumongousObjectTest has humongous objects, // these logs should be displayed. output.shouldContain("Live humongous"); - output.shouldContain("Reclaim humongous region"); + output.shouldContain("Dead humongous region"); output.shouldHaveExitValue(0); } diff --git a/hotspot/test/gc/g1/TestGCLogMessages.java b/hotspot/test/gc/g1/TestGCLogMessages.java index ee338013f4b..5e19d4f2d14 100644 --- a/hotspot/test/gc/g1/TestGCLogMessages.java +++ b/hotspot/test/gc/g1/TestGCLogMessages.java @@ -23,7 +23,7 @@ /* * @test TestGCLogMessages - * @bug 8035406 8027295 8035398 8019342 8027959 + * @bug 8035406 8027295 8035398 8019342 8027959 8048179 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. * @key gc @@ -54,6 +54,7 @@ public class TestGCLogMessages { output.shouldNotContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); output.shouldNotContain("[Non-Young Free CSet"); + output.shouldNotContain("[Humongous Register"); output.shouldNotContain("[Humongous Reclaim"); output.shouldHaveExitValue(0); @@ -72,9 +73,10 @@ public class TestGCLogMessages { output.shouldContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); output.shouldNotContain("[Non-Young Free CSet"); - output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Register"); output.shouldNotContain("[Humongous Total"); output.shouldNotContain("[Humongous Candidate"); + output.shouldContain("[Humongous Reclaim"); output.shouldNotContain("[Humongous Reclaimed"); output.shouldHaveExitValue(0); @@ -95,9 +97,10 @@ public class TestGCLogMessages { output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); output.shouldContain("[Non-Young Free CSet"); - output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Register"); output.shouldContain("[Humongous Total"); output.shouldContain("[Humongous Candidate"); + output.shouldContain("[Humongous Reclaim"); output.shouldContain("[Humongous Reclaimed"); output.shouldHaveExitValue(0); } From b8092a16621ca13782e2d56670fff09a60a24871 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Tue, 13 Jan 2015 16:38:29 +0100 Subject: [PATCH 46/72] 8068889: Calling a @FunctionalInterface from JS leaks internal objects Reviewed-by: jlaskey, sundar --- .../internal/runtime/linker/Bootstrap.java | 2 +- .../runtime/linker/NashornBeansLinker.java | 75 ++++++++++++++++++- .../runtime/linker/NashornBottomLinker.java | 60 --------------- .../api/scripting/ScriptEngineTest.java | 39 ++++++++++ 4 files changed, 113 insertions(+), 63 deletions(-) diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java index 749c4728ae5..173bfc3458c 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -189,7 +189,7 @@ public final class Bootstrap { * @return true if the obj is an instance of @FunctionalInterface interface */ public static boolean isFunctionalInterfaceObject(final Object obj) { - return !JSType.isPrimitive(obj) && (NashornBottomLinker.getFunctionalInterfaceMethod(obj.getClass()) != null); + return !JSType.isPrimitive(obj) && (NashornBeansLinker.getFunctionalInterfaceMethod(obj.getClass()) != null); } /** diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java index d5133cb300e..9f38baf9e97 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java @@ -25,20 +25,29 @@ package jdk.nashorn.internal.runtime.linker; +import static jdk.nashorn.internal.lookup.Lookup.MH; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.linker.ConversionComparator.Comparison; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardingDynamicLinker; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; +import jdk.internal.dynalink.support.Guards; import jdk.internal.dynalink.support.Lookup; import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.ConsString; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.options.Options; /** @@ -68,19 +77,49 @@ public class NashornBeansLinker implements GuardingDynamicLinker { FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class); } + // cache of @FunctionalInterface method of implementor classes + private static final ClassValue FUNCTIONAL_IFACE_METHOD = new ClassValue() { + @Override + protected Method computeValue(final Class type) { + return findFunctionalInterfaceMethod(type); + } + }; + private final BeansLinker beansLinker = new BeansLinker(); @Override public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { - if (linkRequest.getReceiver() instanceof ConsString) { + final Object self = linkRequest.getReceiver(); + final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor(); + if (self instanceof ConsString) { // In order to treat ConsString like a java.lang.String we need a link request with a string receiver. final Object[] arguments = linkRequest.getArguments(); arguments[0] = ""; - final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(linkRequest.getCallSiteDescriptor(), arguments); + final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(desc, arguments); final GuardedInvocation invocation = getGuardedInvocation(beansLinker, forgedLinkRequest, linkerServices); // If an invocation is found we add a filter that makes it work for both Strings and ConsStrings. return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING); } + + if ("call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { + // Support dyn:call on any object that supports some @FunctionalInterface + // annotated interface. This way Java method, constructor references or + // implementations of java.util.function.* interfaces can be called as though + // those are script functions. + final Method m = getFunctionalInterfaceMethod(self.getClass()); + if (m != null) { + final MethodType callType = desc.getMethodType(); + // 'callee' and 'thiz' passed from script + actual arguments + if (callType.parameterCount() != m.getParameterCount() + 2) { + throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self)); + } + return new GuardedInvocation( + // drop 'thiz' passed from the script. + MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)), + Guards.getInstanceOfGuard(m.getDeclaringClass())).asTypeSafeReturn( + new NashornBeansLinkerServices(linkerServices), callType); + } + } return getGuardedInvocation(beansLinker, linkRequest, linkerServices); } @@ -137,6 +176,38 @@ public class NashornBeansLinker implements GuardingDynamicLinker { return arg instanceof ConsString ? arg.toString() : arg; } + private static Method findFunctionalInterfaceMethod(final Class clazz) { + if (clazz == null) { + return null; + } + + for (final Class iface : clazz.getInterfaces()) { + // check accessiblity up-front + if (! Context.isAccessibleClass(iface)) { + continue; + } + + // check for @FunctionalInterface + if (iface.isAnnotationPresent(FunctionalInterface.class)) { + // return the first abstract method + for (final Method m : iface.getMethods()) { + if (Modifier.isAbstract(m.getModifiers())) { + return m; + } + } + } + } + + // did not find here, try super class + return findFunctionalInterfaceMethod(clazz.getSuperclass()); + } + + // Returns @FunctionalInterface annotated interface's single abstract + // method. If not found, returns null. + static Method getFunctionalInterfaceMethod(final Class clazz) { + return FUNCTIONAL_IFACE_METHOD.get(clazz); + } + private static class NashornBeansLinkerServices implements LinkerServices { private final LinkerServices linkerServices; diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java index 4ed6e3a26ca..2cbbf06577c 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java @@ -30,9 +30,6 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import jdk.internal.dynalink.CallSiteDescriptor; @@ -45,7 +42,6 @@ import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.Guards; import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; @@ -95,22 +91,6 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo } throw typeError("not.a.function", ScriptRuntime.safeToString(self)); case "call": - // Support dyn:call on any object that supports some @FunctionalInterface - // annotated interface. This way Java method, constructor references or - // implementations of java.util.function.* interfaces can be called as though - // those are script functions. - final Method m = getFunctionalInterfaceMethod(self.getClass()); - if (m != null) { - final MethodType callType = desc.getMethodType(); - // 'callee' and 'thiz' passed from script + actual arguments - if (callType.parameterCount() != m.getParameterCount() + 2) { - throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self)); - } - return Bootstrap.asTypeSafeReturn(new GuardedInvocation( - // drop 'thiz' passed from the script. - MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)), - Guards.getInstanceOfGuard(m.getDeclaringClass())), linkerServices, desc); - } if(BeansLinker.isDynamicConstructor(self)) { throw typeError("constructor.requires.new", ScriptRuntime.safeToString(self)); } @@ -218,44 +198,4 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo } return ScriptRuntime.safeToString(linkRequest.getArguments()[1]); } - - // cache of @FunctionalInterface method of implementor classes - private static final ClassValue FUNCTIONAL_IFACE_METHOD = new ClassValue() { - @Override - protected Method computeValue(final Class type) { - return findFunctionalInterfaceMethod(type); - } - - private Method findFunctionalInterfaceMethod(final Class clazz) { - if (clazz == null) { - return null; - } - - for (final Class iface : clazz.getInterfaces()) { - // check accessiblity up-front - if (! Context.isAccessibleClass(iface)) { - continue; - } - - // check for @FunctionalInterface - if (iface.isAnnotationPresent(FunctionalInterface.class)) { - // return the first abstract method - for (final Method m : iface.getMethods()) { - if (Modifier.isAbstract(m.getModifiers())) { - return m; - } - } - } - } - - // did not find here, try super class - return findFunctionalInterfaceMethod(clazz.getSuperclass()); - } - }; - - // Returns @FunctionalInterface annotated interface's single abstract - // method. If not found, returns null. - static Method getFunctionalInterfaceMethod(final Class clazz) { - return FUNCTIONAL_IFACE_METHOD.get(clazz); - } } diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index e2e28852d5f..751b505d8f9 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -30,12 +30,16 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; + import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Function; import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.Invocable; @@ -680,6 +684,41 @@ public class ScriptEngineTest { assertNull(value); } + // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. + @Test + public void functionalInterfaceStringTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("f", new Function() { + @Override + public String apply(String t) { + invoked.set(true); + return t; + } + }); + assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); + assertTrue(invoked.get()); + } + + // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. + @Test + public void functionalInterfaceObjectTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("c", new Consumer() { + @Override + public void accept(Object t) { + assertTrue(t instanceof ScriptObjectMirror); + assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); + invoked.set(true); + } + }); + e.eval("var x = 'xy'; x += 'z';c({a:x})"); + assertTrue(invoked.get()); + } + private static void checkProperty(final ScriptEngine e, final String name) throws ScriptException { final String value = System.getProperty(name); From 242419de96cddfd161ae83d5ff1a0805165b7d09 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Wed, 14 Jan 2015 15:54:18 +0100 Subject: [PATCH 47/72] 8068573: POJO setter using [] syntax throws an exception Reviewed-by: lagergren, jlaskey --- .../dynalink/beans/AbstractJavaLinker.java | 7 ++- .../dynalink/beans/OverloadedMethod.java | 1 - .../dynalink/support/TypeUtilities.java | 22 +++---- .../internal/runtime/linker/Bootstrap.java | 6 +- .../test/script/basic/JDK-8020324.js.EXPECTED | 4 +- nashorn/test/script/basic/JDK-8068573.js | 57 +++++++++++++++++++ 6 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8068573.js diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java index b8e8a3df20b..cf1b11d3871 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java @@ -491,8 +491,9 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be // valid for us to convert return values proactively. Also, since we don't know what setters will be - // invoked, we'll conservatively presume Object return type. - final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); + // invoked, we'll conservatively presume Object return type. The one exception is void return. + final MethodType origType = callSiteDescriptor.getMethodType(); + final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class); // What's below is basically: // foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation), @@ -508,7 +509,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // Bind property setter handle to the expected setter type and linker services. Type is // MethodHandle(Object, String, Object) final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, - CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices); + callSiteDescriptor.changeMethodType(setterType), linkerServices); // Cast getter to MethodHandle(O, N, V) final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType( diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java index 70ec495a7ac..c8d500725b2 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java @@ -123,7 +123,6 @@ class OverloadedMethod { varArgMethods = new ArrayList<>(methodHandles.size()); final int argNum = callSiteType.parameterCount(); for(MethodHandle mh: methodHandles) { - mh = mh.asType(mh.type().changeReturnType(commonRetType)); if(mh.isVarargsCollector()) { final MethodHandle asFixed = mh.asFixedArity(); if(argNum == asFixed.type().parameterCount()) { diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java index bf4771b2a49..78d42ab127e 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java @@ -118,17 +118,13 @@ public class TypeUtilities { public static Class getCommonLosslessConversionType(final Class c1, final Class c2) { if(c1 == c2) { return c1; + } else if (c1 == void.class || c2 == void.class) { + return Object.class; } else if(isConvertibleWithoutLoss(c2, c1)) { return c1; } else if(isConvertibleWithoutLoss(c1, c2)) { return c2; - } - if(c1 == void.class) { - return c2; - } else if(c2 == void.class) { - return c1; - } - if(c1.isPrimitive() && c2.isPrimitive()) { + } else if(c1.isPrimitive() && c2.isPrimitive()) { if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) { // byte + char = int return int.class; @@ -268,20 +264,24 @@ public class TypeUtilities { } /** - * Determines whether a type can be converted to another without losing any - * precision. + * Determines whether a type can be converted to another without losing any precision. As a special case, + * void is considered convertible only to Object and void, while anything can be converted to void. This + * is because a target type of void means we don't care about the value, so the conversion is always + * permissible. * * @param sourceType the source type * @param targetType the target type * @return true if lossless conversion is possible */ public static boolean isConvertibleWithoutLoss(final Class sourceType, final Class targetType) { - if(targetType.isAssignableFrom(sourceType)) { + if(targetType.isAssignableFrom(sourceType) || targetType == void.class) { return true; } if(sourceType.isPrimitive()) { if(sourceType == void.class) { - return false; // Void can't be losslessly represented by any type + // Void should be losslessly representable by Object, either as null or as a custom value that + // can be set with DynamicLinkerFactory.setAutoConversionStrategy. + return targetType == Object.class; } if(targetType.isPrimitive()) { return isProperPrimitiveLosslessSubtype(sourceType, targetType); diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java index 173bfc3458c..cd4dd3b7cc3 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -68,6 +68,8 @@ public final class Bootstrap { private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); + private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED); + /** * The default dynalink relink threshold for megamorphisism is 8. In the case * of object fields only, it is fine. However, with dual fields, in order to get @@ -481,14 +483,16 @@ public final class Bootstrap { private static MethodHandle unboxReturnType(final MethodHandle target, final MethodType newType) { final MethodType targetType = target.type(); final Class oldReturnType = targetType.returnType(); + final Class newReturnType = newType.returnType(); if (TypeUtilities.isWrapperType(oldReturnType)) { - final Class newReturnType = newType.returnType(); if (newReturnType.isPrimitive()) { // The contract of setAutoConversionStrategy is such that the difference between newType and targetType // can only be JLS method invocation conversions. assert TypeUtilities.isMethodInvocationConvertible(oldReturnType, newReturnType); return MethodHandles.explicitCastArguments(target, targetType.changeReturnType(newReturnType)); } + } else if (oldReturnType == void.class && newReturnType == Object.class) { + return MethodHandles.filterReturnValue(target, VOID_TO_OBJECT); } return target; } diff --git a/nashorn/test/script/basic/JDK-8020324.js.EXPECTED b/nashorn/test/script/basic/JDK-8020324.js.EXPECTED index 500f46b9f04..9ebae802598 100644 --- a/nashorn/test/script/basic/JDK-8020324.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8020324.js.EXPECTED @@ -17,7 +17,7 @@ bean.readWrite: 17 bean.readWrite = 18: 18 obj1.readWrite: 18 obj1.getReadWrite(): 18 -obj1.setReadWrite(19): null +obj1.setReadWrite(19): undefined obj1.readWrite: 19 bean.readWrite: 19 @@ -52,7 +52,7 @@ PropertyBind.staticReadWrite: 25 PropertyBind.staticReadWrite = 26: 26 obj2.staticReadWrite: 26 obj2.getStaticReadWrite(): 26 -obj2.setStaticReadWrite(27): null +obj2.setStaticReadWrite(27): undefined obj2.staticReadWrite: 27 PropertyBind.staticReadWrite: 27 diff --git a/nashorn/test/script/basic/JDK-8068573.js b/nashorn/test/script/basic/JDK-8068573.js new file mode 100644 index 00000000000..73f71582a8b --- /dev/null +++ b/nashorn/test/script/basic/JDK-8068573.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8068573: POJO setter using [] syntax throws an exception + * + * @test + * @run + */ + +// Invoke a setter using []. It's important that the setter returns void. +var pb = new (Java.type("jdk.nashorn.test.models.PropertyBind")) +var n = "writeOnly"; +pb[n] = 2; +Assert.assertEquals(pb.peekWriteOnly(), 2); + +// Invoke an overloaded setter using []. It's important that one of the +// overloads returns void. +var os = new (Java.type("jdk.nashorn.test.models.OverloadedSetter")) +var n2 = "color"; +os[n2] = 3; // exercise int overload +Assert.assertEquals(os.peekColor(), "3"); +os[n2] = "blue"; // exercise string overload +Assert.assertEquals(os.peekColor(), "blue"); +for each(var x in [42, "42"]) { + os[n2] = x; // exercise both overloads in the same call site + Assert.assertEquals(os.peekColor(), "42"); +} + +// Invoke an overloaded method using [], repeatedly in the same call +// site. It's important that one of the overloads returns void. +var n3="foo"; +var param=["xyz", 1, "zyx", 2]; +var expected=["boo", void 0, "boo", void 0]; +for(var i in param) { + Assert.assertEquals(os[n3](param[i]), expected[i]); +} From 7090b1cdf55fa58dc0963521f8e194f25ca463ae Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Wed, 14 Jan 2015 16:29:39 +0100 Subject: [PATCH 48/72] 8068994: Forgot to add a test model to JDK-8068573 Reviewed-by: lagergren, sundar --- .../nashorn/test/models/OverloadedSetter.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java diff --git a/nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java new file mode 100644 index 00000000000..810ae2f12da --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.test.models; + +public class OverloadedSetter { + private String color; + + public void setColor(final int x) { + this.color = Integer.toString(x); + } + + public void setColor(final String x) { + this.color = x; + } + + public String peekColor() { + return color; + } + + public void foo(final int x) { + } + + public String foo(final String x) { + return "boo"; + } +} From 4935529d4dde746eee5d847c409a99e1a6426b10 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Wed, 14 Jan 2015 18:25:01 +0100 Subject: [PATCH 49/72] 8069002: NPE on invoking null (8068889 regression) Reviewed-by: jlaskey, sundar --- .../runtime/linker/NashornBeansLinker.java | 2 +- nashorn/test/script/basic/JDK-8069002.js | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8069002.js diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java index 9f38baf9e97..da12af2d9b2 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java @@ -101,7 +101,7 @@ public class NashornBeansLinker implements GuardingDynamicLinker { return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING); } - if ("call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { + if (self != null && "call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { // Support dyn:call on any object that supports some @FunctionalInterface // annotated interface. This way Java method, constructor references or // implementations of java.util.function.* interfaces can be called as though diff --git a/nashorn/test/script/basic/JDK-8069002.js b/nashorn/test/script/basic/JDK-8069002.js new file mode 100644 index 00000000000..29d75516855 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8069002.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8069002: NPE on invoking null (8068889 regression) + * + * @test + * @run + */ + +try { + null(); +} catch (e) { + Assert.assertTrue(e instanceof TypeError); +} From 7882032236ec549fd19b3da1eeeefa899357a809 Mon Sep 17 00:00:00 2001 From: Lev Priima Date: Wed, 14 Jan 2015 21:35:52 +0300 Subject: [PATCH 50/72] 8067471: Use private static final char[0] for empty Strings Reviewed-by: igerasim, redestad, shade --- .../share/classes/java/lang/String.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index a44682a5b44..9ff32f48a60 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -135,7 +135,7 @@ public final class String * unnecessary since Strings are immutable. */ public String() { - this.value = new char[0]; + this.value = "".value; } /** @@ -175,7 +175,7 @@ public final class String * not affect the newly created string. * * @param value - * Array that is the source of characters + * Array that is the source of characters * * @param offset * The initial offset @@ -191,8 +191,14 @@ public final class String if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } - if (count < 0) { - throw new StringIndexOutOfBoundsException(count); + if (count <= 0) { + if (count < 0) { + throw new StringIndexOutOfBoundsException(count); + } + if (offset <= value.length) { + this.value = "".value; + return; + } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { @@ -233,8 +239,14 @@ public final class String if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } - if (count < 0) { - throw new StringIndexOutOfBoundsException(count); + if (count <= 0) { + if (count < 0) { + throw new StringIndexOutOfBoundsException(count); + } + if (offset <= codePoints.length) { + this.value = "".value; + return; + } } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { @@ -246,11 +258,11 @@ public final class String // Pass 1: Compute precise size of char[] int n = count; for (int i = offset; i < end; i++) { - int c = codePoints[i]; - if (Character.isBmpCodePoint(c)) - continue; - else if (Character.isValidCodePoint(c)) - n++; + int c = codePoints[i]; + if (Character.isBmpCodePoint(c)) + continue; + else if (Character.isValidCodePoint(c)) + n++; else throw new IllegalArgumentException(Integer.toString(c)); } @@ -783,7 +795,7 @@ public final class String * subarray of {@code dst} starting at index {@code dstBegin} * and ending at index: *
-     *     dstbegin + (srcEnd-srcBegin) - 1
+     *     dstBegin + (srcEnd-srcBegin) - 1
      * 
* * @param srcBegin index of the first character in the string @@ -828,7 +840,7 @@ public final class String * dst} starting at index {@code dstBegin} and ending at index: * *
-     *     dstbegin + (srcEnd-srcBegin) - 1
+     *     dstBegin + (srcEnd-srcBegin) - 1
      * 
* * @deprecated This method does not properly convert characters into From fa39b2bbf29195c8d19424f7a11ff8319de71f61 Mon Sep 17 00:00:00 2001 From: Andrey Nazarov Date: Wed, 14 Jan 2015 12:09:38 -0800 Subject: [PATCH 51/72] 8067437: New tests for mJRE feature removal Reviewed-by: darcy, ksrini --- jdk/test/tools/launcher/Arrrghs.java | 131 +---------- jdk/test/tools/launcher/MultipleJRE.sh | 59 ----- .../tools/launcher/MultipleJRERemoved.java | 212 ++++++++++++++++++ 3 files changed, 214 insertions(+), 188 deletions(-) create mode 100644 jdk/test/tools/launcher/MultipleJRERemoved.java diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java index 0096f22ad3b..c7f53d3251d 100644 --- a/jdk/test/tools/launcher/Arrrghs.java +++ b/jdk/test/tools/launcher/Arrrghs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,12 +30,10 @@ * @run main/othervm Arrrghs */ -import java.io.BufferedReader; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -48,9 +46,6 @@ public class Arrrghs extends TestHelper { private Arrrghs(){} /** * This class provides various tests for arguments processing. - * A group of tests to ensure that arguments are passed correctly to - * a child java process upon a re-exec, this typically happens when - * a version other than the one being executed is requested by the user. * * History: these set of tests were part of Arrrghs.sh. The MKS shell * implementations were notoriously buggy. Implementing these tests purely @@ -58,12 +53,6 @@ public class Arrrghs extends TestHelper { * */ - // The version string to force a re-exec - final static String VersionStr = "-version:1.1+"; - - // The Cookie or the pattern we match in the debug output. - final static String Cookie = "ReExec Args: "; - /* * SIGH, On Windows all strings are quoted, we need to unwrap it */ @@ -78,122 +67,6 @@ public class Arrrghs extends TestHelper { return in; } - /* - * This method detects the cookie in the output stream of the process. - */ - private boolean detectCookie(InputStream istream, - String expectedArguments) throws IOException { - BufferedReader rd = new BufferedReader(new InputStreamReader(istream)); - boolean retval = false; - - String in = rd.readLine(); - while (in != null) { - if (debug) System.out.println(in); - if (in.startsWith(Cookie)) { - String detectedArgument = removeExtraQuotes(in.substring(Cookie.length())); - if (expectedArguments.equals(detectedArgument)) { - retval = true; - } else { - System.out.println("Error: Expected Arguments\t:'" + - expectedArguments + "'"); - System.out.println(" Detected Arguments\t:'" + - detectedArgument + "'"); - } - // Return the value asap if not in debug mode. - if (!debug) { - rd.close(); - istream.close(); - return retval; - } - } - in = rd.readLine(); - } - return retval; - } - - private boolean doReExecTest0(ProcessBuilder pb, String expectedArguments) { - boolean retval = false; - try { - pb.redirectErrorStream(true); - Process p = pb.start(); - retval = detectCookie(p.getInputStream(), expectedArguments); - p.waitFor(); - p.destroy(); - } catch (Exception ex) { - ex.printStackTrace(); - throw new RuntimeException(ex.getMessage()); - } - return retval; - } - - /** - * This method returns true if the expected and detected arguments are the same. - * Quoting could cause dissimilar testArguments and expected arguments. - */ - int doReExecTest(String testArguments, String expectedPattern) { - ProcessBuilder pb = new ProcessBuilder(javaCmd, - VersionStr, testArguments); - - Map env = pb.environment(); - env.put(JLDEBUG_KEY, "true"); - return doReExecTest0(pb, testArguments) ? 0 : 1; - } - - /** - * A convenience method for identical test pattern and expected arguments - */ - int doReExecTest(String testPattern) { - return doReExecTest(testPattern, testPattern); - } - - @Test - void testQuoteParsingThroughReExec() { - /* - * Tests for 6214916 - * These tests require that a JVM (any JVM) be installed in the system registry. - * If none is installed, skip this test. - */ - TestResult tr = doExec(javaCmd, VersionStr, "-version"); - if (!tr.isOK()) { - System.err.println("Warning:Argument Passing Tests were skipped, " + - "no java found in system registry."); - return; - } - - // Basic test - testExitValue += doReExecTest("-a -b -c -d"); - - // Basic test with many spaces - testExitValue += doReExecTest("-a -b -c -d"); - - // Quoted whitespace does matter ? - testExitValue += doReExecTest("-a \"\"-b -c\"\" -d"); - - - // Escaped quotes outside of quotes as literals - testExitValue += doReExecTest("-a \\\"-b -c\\\" -d"); - - // Check for escaped quotes inside of quotes as literal - testExitValue += doReExecTest("-a \"-b \\\"stuff\\\"\" -c -d"); - - // A quote preceeded by an odd number of slashes is a literal quote - testExitValue += doReExecTest("-a -b\\\\\\\" -c -d"); - - // A quote preceeded by an even number of slashes is a literal quote - // see 6214916. - testExitValue += doReExecTest("-a -b\\\\\\\\\" -c -d"); - - // Make sure that whitespace doesn't interfere with the removal of the - // appropriate tokens. (space-tab-space preceeds -jre-restict-search). - testExitValue += doReExecTest("-a -b \t -jre-restrict-search -c -d", "-a -b -c -d"); - - // Make sure that the mJRE tokens being stripped, aren't stripped if - // they happen to appear as arguments to the main class. - testExitValue += doReExecTest("foo -version:1.1+"); - - System.out.println("Completed arguments quoting tests with " - + testExitValue + " errors"); - } // the pattern we hope to see in the output static final Pattern ArgPattern = Pattern.compile("\\s*argv\\[[0-9]*\\].*=.*"); diff --git a/jdk/test/tools/launcher/MultipleJRE.sh b/jdk/test/tools/launcher/MultipleJRE.sh index a0576b2288c..fabfbca1d9c 100644 --- a/jdk/test/tools/launcher/MultipleJRE.sh +++ b/jdk/test/tools/launcher/MultipleJRE.sh @@ -89,36 +89,6 @@ TestSyntax() { fi } -# -# Shell routine to ensure help page does not include mjre options -# -TestHelp() { - mess="`$JAVA -help 2>&1`" - # make sure it worked - if [ $? -ne 0 ]; then - echo "java -help failed ????" - exit 1 - fi - - echo $mess | grep '\-version:' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option version:" - exit 1 - fi - - echo $mess | grep '\-jre-restrict-search' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option jre-restrict-search" - exit 1 - fi - - echo $mess | grep '\-no-jre-restrict-search' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option no-jre-restrict-search" - exit 1 - fi -} - # # Just as the name says. We sprinkle these in the appropriate location # in the test file system and they just say who they are pretending to be. @@ -461,33 +431,4 @@ if [ -x /usr/bin/zipnote ]; then LaunchVM "" "${RELEASE}" fi -# -# Now test specification of mJRE -# -# In some cases this should result in failure of the command, -# in some cases, a warning messages, with the command succeeding. -# - - # Commandline use of "-version:" should fail - # with a message containing "no longer supported" - LaunchVM "-version:1.10+" "Error: Specifying an alternate JDK/JRE" - LaunchVM "-version:prettymuchanything" "Error: Specifying an alternate JDK/JRE" - - # Commandline use of "-jre-restrict-search" should now fail - LaunchVM "-jre-restrict-search" "\-jre\-no\-restrict\-search are also no longer valid" - # Commandline use of "-jre-no-restrict-search" should now fail - LaunchVM "-jre-no-restrict-search" "\-jre\-no\-restrict\-search are also no longer valid" - - - # mJRE directives to use a specific version should be flagged - # with a warning, but the jar should be executed with the - # current jre - CreateFullJar "junk request" "" - LaunchVM "" "${RELEASE}" - # Going to silently ignore JRE-Version setting in jar file manifest - #LaunchVM "" "warning: The jarfile JRE-Version" - - # Verify help does not contain obsolete options - TestHelp - exit 0 diff --git a/jdk/test/tools/launcher/MultipleJRERemoved.java b/jdk/test/tools/launcher/MultipleJRERemoved.java new file mode 100644 index 00000000000..b13e7a2913b --- /dev/null +++ b/jdk/test/tools/launcher/MultipleJRERemoved.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8067437 + * @summary Verify Multiple JRE version support has been removed. + * @build TestHelper + * @run main MultipleJRERemoved + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.util.*; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; + +public class MultipleJRERemoved extends TestHelper { + + public static final String VERSION_JAR = "version.jar"; + public static final String PRINT_VERSION_CLASS = "PrintVersion"; + private final File javaFile = new File(PRINT_VERSION_CLASS + ".java"); + private final File clsFile = new File(PRINT_VERSION_CLASS + ".class"); + + private MultipleJRERemoved() { + } + + /** + * @param args the command line arguments + * @throws java.io.FileNotFoundException + */ + public static void main(String[] args) throws Exception { + MultipleJRERemoved a = new MultipleJRERemoved(); + a.run(args); + } + + /** + * Check all combinations of flags: "-version:", "-jre-restrict-search", "-jre-no-restrict-search". Test expects to see errors. + */ + @Test + public void allFlagCombinations() throws IOException { + final Pattern newLine = Pattern.compile("\n"); + createJar(Collections.emptyMap()); + + for (Flag flag1 : Flag.values()) { + for (Flag flag2 : Flag.values()) { + for (Flag flag3 : Flag.values()) { + List flags = Stream.of(flag1, flag2, flag3) + .filter(f -> !Flag.EMPTY.equals(f)) + .collect(Collectors.toList()); + + if (flags.size() == 0) continue; + + List flagValues = flags.stream() + .map(Flag::value) + .collect(Collectors.toList()); + + List errorMessages = flags.stream() + .map(Flag::errorMessage) + .flatMap(newLine::splitAsStream) + .collect(Collectors.toList()); + + List jarCmd = new ArrayList<>(); + jarCmd.add(javaCmd); + jarCmd.addAll(flagValues); + jarCmd.add("-jar"); + jarCmd.add("version.jar"); + + check(jarCmd, errorMessages); + + List cmd = new ArrayList<>(); + cmd.add(javaCmd); + cmd.addAll(flagValues); + cmd.add(PRINT_VERSION_CLASS); + + check(cmd, errorMessages); + } + } + } + } + + private void check(List cmd, List errorMessages) { + TestResult tr = doExec(cmd.toArray(new String[cmd.size()])); + tr.checkNegative(); + tr.isNotZeroOutput(); + errorMessages.forEach(tr::contains); + + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("test case: failed\n" + cmd); + } + } + + /** + * Verifies that java -help output doesn't contain information about "mJRE" flags. + */ + @Test + public void javaHelp() { + TestResult tr = doExec(javaCmd, "-help"); + tr.checkPositive(); + tr.isNotZeroOutput(); + tr.notContains("-version:"); + tr.notContains("-jre-restrict-search"); + tr.notContains("-jre-no-restrict-search"); + tr.notContains("-no-jre-restrict-search"); //it's not a typo in flag name. + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("Failed. java -help output contains obsolete flags.\n"); + } + } + + /** + * Verifies that java -jar version.jar output ignores "mJRE" manifest directives. + */ + @Test + public void manifestDirectives() throws IOException { + Map manifest = new TreeMap<>(); + manifest.put("JRE-Version", "1.8"); + manifest.put("JRE-Restrict-Search", "1.8"); + createJar(manifest); + + TestResult tr = doExec(javaCmd, "-jar", VERSION_JAR); + tr.checkPositive(); + tr.contains(System.getProperty("java.version")); + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("Failed.\n"); + } + } + + private void emitFile() throws IOException { + List scr = new ArrayList<>(); + scr.add("public class PrintVersion {"); + scr.add(" public static void main(String... args) {"); + scr.add(" System.out.println(System.getProperty(\"java.version\"));"); + scr.add(" }"); + scr.add("}"); + createFile(javaFile, scr); + compile(javaFile.getName()); + } + + private void createJar(Map manifestAttributes) throws IOException { + emitFile(); + + Manifest manifest = new Manifest(); + final Attributes mainAttributes = manifest.getMainAttributes(); + mainAttributes.putValue("Manifest-Version", "1.0"); + mainAttributes.putValue("Main-Class", PRINT_VERSION_CLASS); + manifestAttributes.forEach(mainAttributes::putValue); + + try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(VERSION_JAR), manifest)) { + jar.putNextEntry(new ZipEntry(PRINT_VERSION_CLASS + ".class")); + jar.write(Files.readAllBytes(clsFile.toPath())); + jar.closeEntry(); + } finally { + javaFile.delete(); + } + } + + private enum Flag { + EMPTY("", ""), + VERSION("-version:1.9", "Error: Specifying an alternate JDK/JRE version is no longer supported.\n" + + "The use of the flag '-version:' is no longer valid.\n" + + "Please download and execute the appropriate version."), + JRE_RESTRICT_SEARCH("-jre-restrict-search", "Error: Specifying an alternate JDK/JRE is no longer supported.\n" + + "The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."), + JRE_NO_RESTRICT_SEARCH("-jre-no-restrict-search", "Error: Specifying an alternate JDK/JRE is no longer supported.\n" + + "The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."); + private final String flag; + private final String errorMessage; + + Flag(String flag, String errorMessage) { + this.flag = flag; + this.errorMessage = errorMessage; + } + + String value() { + return flag; + } + + String errorMessage() { + return errorMessage; + } + } +} From 1144804378e48d743b6b42357a3f2a25220eddda Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 14 Jan 2015 16:44:59 -0800 Subject: [PATCH 52/72] 8068948: Update java.base module to use new try-with-resources statement Reviewed-by: alanb, igerasim --- jdk/src/java.base/unix/classes/java/io/FileDescriptor.java | 4 ++-- jdk/src/java.base/windows/classes/java/io/FileDescriptor.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java index 35518e4493d..fefb1b53e4a 100644 --- a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java +++ b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,7 +214,7 @@ public final class FileDescriptor { if (!closed) { closed = true; IOException ioe = null; - try (Closeable c = releaser) { + try (releaser) { if (otherParents != null) { for (Closeable referent : otherParents) { try { diff --git a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java index 0ce43ef1c9d..bd82be034e5 100644 --- a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java +++ b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,7 +212,7 @@ public final class FileDescriptor { if (!closed) { closed = true; IOException ioe = null; - try (Closeable c = releaser) { + try (releaser) { if (otherParents != null) { for (Closeable referent : otherParents) { try { From e7f1a050d3a63de93517d1f58a7ab0794420cc5d Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 15 Jan 2015 10:18:31 +0530 Subject: [PATCH 53/72] 8068985: Wrong 'this' bound to eval call within a function when caller's 'this' is a Java object Reviewed-by: jlaskey, attila --- .../jdk/nashorn/internal/runtime/Context.java | 2 +- nashorn/test/script/basic/JDK-8068985.js | 51 +++++++++++++++++++ .../test/script/basic/JDK-8068985.js.EXPECTED | 10 ++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8068985.js create mode 100644 nashorn/test/script/basic/JDK-8068985.js.EXPECTED diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java index b1342c7e528..5a791dc88c7 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java @@ -703,7 +703,7 @@ public final class Context { final ScriptFunction func = getProgramFunction(clazz, scope); Object evalThis; if (directEval) { - evalThis = callThis instanceof ScriptObject || strictFlag ? callThis : global; + evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global; } else { evalThis = global; } diff --git a/nashorn/test/script/basic/JDK-8068985.js b/nashorn/test/script/basic/JDK-8068985.js new file mode 100644 index 00000000000..498374512fa --- /dev/null +++ b/nashorn/test/script/basic/JDK-8068985.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8068985: Wrong 'this' bound to eval call within a function when caller's 'this' is a Java object + * + * @test + * @run + */ + +function func(arg) { + (function() { print(eval('this')); }).call(arg); +} + +// primitives +func(undefined); +func(null); +func(34.23); +func("hello"); +func(false); + +// script objects +func(this); +func({}); +func({ toString: function() { return "foo" } }); + +// java objects +func(new java.util.Vector()); +var m = new java.util.HashMap(); +m.put("foo", "bar"); +func(m); diff --git a/nashorn/test/script/basic/JDK-8068985.js.EXPECTED b/nashorn/test/script/basic/JDK-8068985.js.EXPECTED new file mode 100644 index 00000000000..7a218e4de7a --- /dev/null +++ b/nashorn/test/script/basic/JDK-8068985.js.EXPECTED @@ -0,0 +1,10 @@ +[object global] +[object global] +34.23 +hello +false +[object global] +[object Object] +foo +[] +{foo=bar} From 7dccb4a74e529fc906d73b3aa44cf6c774c891ed Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 15 Jan 2015 10:56:24 +0000 Subject: [PATCH 54/72] 8061297: sun/reflect/CallerSensitive/CallerSensitiveFinder.java should use the JRT FileSystem Reviewed-by: alanb, mchung, psandoz, xiaofeya --- .../CallerSensitiveFinder.java | 119 ++++++++---------- .../MissingCallerSensitive.java | 6 +- 2 files changed, 58 insertions(+), 67 deletions(-) diff --git a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java index 6d81b6eb23c..b1af24f2f83 100644 --- a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java +++ b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java @@ -26,20 +26,22 @@ import com.sun.tools.jdeps.ClassFileReader; import static com.sun.tools.classfile.ConstantPool.*; import java.io.File; import java.io.IOException; -import java.nio.file.FileVisitResult; +import java.io.UncheckedIOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; +import java.util.stream.Stream; /* * @test @@ -52,8 +54,10 @@ import java.util.concurrent.FutureTask; public class CallerSensitiveFinder { private static int numThreads = 3; private static boolean verbose = false; + private final ExecutorService pool; + public static void main(String[] args) throws Exception { - List classes = new ArrayList<>(); + Stream classes = null; String testclasses = System.getProperty("test.classes", "."); int i = 0; while (i < args.length) { @@ -65,25 +69,30 @@ public class CallerSensitiveFinder { if (!p.toFile().exists()) { throw new IllegalArgumentException(arg + " does not exist"); } - classes.add(p); + classes = Stream.of(p); } } - if (classes.isEmpty()) { - classes.addAll(PlatformClassPath.getJREClasses()); - } - CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); + if (classes == null) { + classes = getPlatformClasses(); + } + + CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); + if (!errors.isEmpty()) { throw new RuntimeException(errors.size() + " caller-sensitive methods are missing @CallerSensitive annotation"); } } - private final List csMethodsMissingAnnotation = new ArrayList<>(); + private final List csMethodsMissingAnnotation = + Collections.synchronizedList(new ArrayList<>()); private final ReferenceFinder finder; public CallerSensitiveFinder() { this.finder = new ReferenceFinder(getFilter(), getVisitor()); + pool = Executors.newFixedThreadPool(numThreads); + } private ReferenceFinder.Filter getFilter() { @@ -123,11 +132,17 @@ public class CallerSensitiveFinder { }; } - public List run(List classes) throws IOException, InterruptedException, + public List run(Stream classes)throws IOException, InterruptedException, ExecutionException, ConstantPoolException { - ExecutorService pool = Executors.newFixedThreadPool(numThreads); - for (Path path : classes) { + classes.forEach(this::processPath); + waitForCompletion(); + pool.shutdown(); + return csMethodsMissingAnnotation; + } + + void processPath(Path path) { + try { ClassFileReader reader = ClassFileReader.newInstance(path); for (ClassFile cf : reader.getClassFiles()) { String classFileName = cf.getName(); @@ -137,10 +152,11 @@ public class CallerSensitiveFinder { // - visit and find method references matching the given method name pool.submit(getTask(cf)); } + } catch (IOException x) { + throw new UncheckedIOException(x); + } catch (ConstantPoolException x) { + throw new RuntimeException(x); } - waitForCompletion(); - pool.shutdown(); - return csMethodsMissingAnnotation; } private static final String CALLER_SENSITIVE_ANNOTATION = "Lsun/reflect/CallerSensitive;"; @@ -178,61 +194,34 @@ public class CallerSensitiveFinder { for (FutureTask t : tasks) { t.get(); } + if (tasks.isEmpty()) { + throw new RuntimeException("No classes found, or specified."); + } System.out.println("Parsed " + tasks.size() + " classfiles"); } - static class PlatformClassPath { - static List getJREClasses() throws IOException { - List result = new ArrayList(); - Path home = Paths.get(System.getProperty("java.home")); + static Stream getPlatformClasses() throws IOException { + Path home = Paths.get(System.getProperty("java.home")); - if (home.endsWith("jre")) { - // jar files in /jre/lib - // skip /lib - result.addAll(addJarFiles(home.resolve("lib"))); - } else if (home.resolve("lib").toFile().exists()) { - // either a JRE or a jdk build image - File classes = home.resolve("classes").toFile(); - if (classes.exists() && classes.isDirectory()) { - // jdk build outputdir - result.add(classes.toPath()); - } - // add other JAR files - result.addAll(addJarFiles(home.resolve("lib"))); - } else { - throw new RuntimeException("\"" + home + "\" not a JDK home"); - } - return result; + // Either an exploded build or an image. + File classes = home.resolve("modules").toFile(); + if (classes.isDirectory()) { + return Stream.of(classes.toPath()); + } else { + return jrtPaths(); } + } - static List addJarFiles(final Path root) throws IOException { - final List result = new ArrayList(); - final Path ext = root.resolve("ext"); - Files.walkFileTree(root, new SimpleFileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException { - if (dir.equals(root) || dir.equals(ext)) { - return FileVisitResult.CONTINUE; - } else { - // skip other cobundled JAR files - return FileVisitResult.SKIP_SUBTREE; - } - } + static Stream jrtPaths() { + FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/")); + Path root = jrt.getPath("/"); - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - File f = file.toFile(); - String fn = f.getName(); - // parse alt-rt.jar as well - if (fn.endsWith(".jar") && !fn.equals("jfxrt.jar")) { - result.add(file); - } - return FileVisitResult.CONTINUE; - } - }); - return result; + try { + return Files.walk(root) + .filter(p -> p.getNameCount() > 1) + .filter(p -> p.toString().endsWith(".class")); + } catch (IOException x) { + throw new UncheckedIOException(x); } } } diff --git a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java index 4fe6ba68a21..66c4398114f 100644 --- a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java +++ b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java @@ -34,11 +34,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.stream.Stream; + public class MissingCallerSensitive { public static void main(String[] args) throws Exception { String testclasses = System.getProperty("test.classes", "."); - List classes = new ArrayList<>(); - classes.add(Paths.get(testclasses, "MissingCallerSensitive.class")); + + Stream classes = Stream.of(Paths.get(testclasses, "MissingCallerSensitive.class")); CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); From 9ca8fd34f276636f440c95ad2e609a39fabd7831 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 15 Jan 2015 12:09:04 +0100 Subject: [PATCH 55/72] 8068902: Solaris build fails with new 10u10 devkit Reviewed-by: tbell --- make/common/NativeCompilation.gmk | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index ad2af57c0fd..d8ca38090df 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -439,8 +439,10 @@ define SetupNativeCompilationInner # Now call add_native_source for each source file we are going to compile. $$(foreach p,$$($1_SRCS), \ $$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \ - $(SYSROOT_CFLAGS) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS),$$($1_CC), \ - $(SYSROOT_CFLAGS) $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS),$$($1_CXX),$$($1_OBJC),$$($1_ASFLAGS)))) + $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $(SYSROOT_CFLAGS), \ + $$($1_CC), \ + $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $(SYSROOT_CFLAGS), \ + $$($1_CXX),$$($1_OBJC),$$($1_ASFLAGS)))) # On windows we need to create a resource file ifeq ($(OPENJDK_TARGET_OS), windows) @@ -576,9 +578,10 @@ define SetupNativeCompilationInner $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_REAL_MAPFILE) \ $$($1_DEBUGINFO_EXTRA_DEPS) $$(call LINKING_MSG,$$($1_BASENAME)) - $$($1_LD) $(SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(LD_OUT_OPTION)$$@ \ - $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) \ - $$($1_EXTRA_LDFLAGS_SUFFIX) + $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ + $(LD_OUT_OPTION)$$@ \ + $$($1_EXPECTED_OBJS) $$($1_RES) \ + $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) $$($1_CREATE_DEBUGINFO_CMDS) # Touch target to make sure it has a later time stamp than the debug # symbol files to avoid unnecessary relinking on rebuild. @@ -603,9 +606,10 @@ define SetupNativeCompilationInner $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_GEN_MANIFEST) \ $$($1_DEBUGINFO_EXTRA_DEPS) $$(call LINKING_EXE_MSG,$$($1_BASENAME)) - $$($1_LDEXE) $(SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(EXE_OUT_OPTION)$$($1_TARGET) \ - $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) \ - $$($1_EXTRA_LDFLAGS_SUFFIX) + $$($1_LDEXE) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ + $(EXE_OUT_OPTION)$$($1_TARGET) \ + $$($1_EXPECTED_OBJS) $$($1_RES) \ + $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) ifneq (,$$($1_GEN_MANIFEST)) $(MT) -nologo -manifest $$($1_GEN_MANIFEST) -outputresource:$$@;#1 endif From a278a118ee071cfd69400a9ce325a165057bafab Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 15 Jan 2015 15:09:37 +0100 Subject: [PATCH 56/72] 8066769: Fix merge errors following JDK-8049367 Reviewed-by: erikj --- common/bin/compare.sh | 331 ++++++++++++++++++++++++----------------- make/Images.gmk | 4 +- make/MakeHelpers.gmk | 2 +- make/ModuleWrapper.gmk | 2 +- 4 files changed, 200 insertions(+), 139 deletions(-) diff --git a/common/bin/compare.sh b/common/bin/compare.sh index 418ca1d3517..1eae597a109 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -22,7 +22,7 @@ # questions. # -# This script is processed by configure before it's usable. It is run from +# This script is processed by configure before it's usable. It is run from # the root of the build directory. @@ -76,10 +76,13 @@ diff_text() { TMP=1 if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then + # Filter out date string, ant version and java version differences. TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ - -e '/[<>] Created-By: .* (Oracle Corporation).*/d') + -e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \ + -e '/[<>] [Corpatin]*)/d' \ + -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') fi if test "x$SUFFIX" = "xjava"; then TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ @@ -92,7 +95,7 @@ diff_text() { -e '/\/\/ java GenerateCharacter.*/d') fi # Ignore date strings in class files. - # On Macosx the system sources for generated java classes produce different output on + # On Macosx the system sources for generated java classes produce different output on # consequtive invocations seemingly randomly. # For example a method parameter randomly named "thePoint" or "aPoint". Ignore this. # Anonymous lambda classes get randomly assigned counters in their names. @@ -100,18 +103,18 @@ diff_text() { # To improve performance when large diffs are found, do a rough filtering of classes # elibeble for these exceptions if $GREP -R -e '[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}' \ - -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \ - -e thePoint -e aPoint -e setItemsPtr \ + -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \ + -e thePoint -e aPoint -e setItemsPtr \ -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null; then $JAVAP -c -constants -l -p "${OTHER_FILE}" > ${OTHER_FILE}.javap $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ - -e '/[0-9]\{2\}\/[0-9]\{2\}\/[0-9]\{4\}/d' \ - -e '/[<>].*Point Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \ - -e '/[<>].*public com\.apple\.jobjc\.Pointer].*public void setItemsPtr(com\.apple\.jobjc\.Pointer].*Point Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \ + -e '/[<>].*public com\.apple\.jobjc\.Pointer].*public void setItemsPtr(com\.apple\.jobjc\.Pointer].*lambda\$[a-zA-Z0-9]*\$[0-9]*/d') fi fi @@ -121,20 +124,19 @@ diff_text() { # Disable this exception since we aren't changing the properties cleaning method yet. # $CAT $OTHER_FILE | $SED -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \ # | $SED -f "$SRC_ROOT/common/makefiles/support/unicode2x.sed" \ -# | $SED -e '/^#/d' -e '/^$/d' \ +# | $SED -e '/^#/d' -e '/^$/d' \ # -e :a -e '/\\$/N; s/\\\n//; ta' \ -# -e 's/^[ \t]*//;s/[ \t]*$//' \ -# -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned +# -e 's/^[ \t]*//;s/[ \t]*$//' \ +# -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned # Filter out date string differences. TMP=$(LC_ALL=C $DIFF $OTHER_FILE.cleaned $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') fi - if test "x$SUFFIX" = "xMF"; then - # Filter out date string differences. + if test "x$SUFFIX" = "xhtml"; then TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ - $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') + $SED -e '/[<>] /d' ) fi if test -n "$TMP"; then echo Files $OTHER_FILE and $THIS_FILE differ @@ -158,7 +160,7 @@ compare_dirs() { (cd $THIS_DIR && $FIND . -type d | $SORT > $WORK_DIR/dirs_this) $DIFF $WORK_DIR/dirs_other $WORK_DIR/dirs_this > $WORK_DIR/dirs_diff - + echo -n Directory structure... if [ -s $WORK_DIR/dirs_diff ]; then echo Differences found. @@ -192,7 +194,7 @@ compare_files() { (cd $OTHER_DIR && $FIND . ! -type d | $SORT > $WORK_DIR/files_other) (cd $THIS_DIR && $FIND . ! -type d | $SORT > $WORK_DIR/files_this) - + $DIFF $WORK_DIR/files_other $WORK_DIR/files_this > $WORK_DIR/files_diff echo -n File names... @@ -236,11 +238,11 @@ compare_permissions() { TP=`ls -l ${THIS_DIR}/$f | awk '{printf("%.10s\n", $1);}'` if [ "$OP" != "$TP" ] then - if [ -z "$found" ]; then echo ; found="yes"; fi - $PRINTF "\told: ${OP} new: ${TP}\t$f\n" + if [ -z "$found" ]; then echo ; found="yes"; fi + $PRINTF "\tother: ${OP} this: ${TP}\t$f\n" fi done - if [ -z "$found" ]; then + if [ -z "$found" ]; then echo "Identical!" else REGRESSIONS=true @@ -265,24 +267,22 @@ compare_file_types() { if [ ! -f ${THIS_DIR}/$f ]; then continue; fi OF=`cd ${OTHER_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` TF=`cd ${THIS_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` - if [ "$f" = "./src.zip" ] || [[ "$f" = *"/Home/src.zip" ]] || [[ "$f" = *"/lib/JObjC.jar" ]] - then - if [ "`echo $OF | $GREP -ic zip`" -gt 0 -a "`echo $TF | $GREP -ic zip`" -gt 0 ] - then - # the way we produces zip-files make it so that directories are stored in old file - # but not in new (only files with full-path) - # this makes file-5.09 report them as different - continue; - fi - fi - if [ "$OF" != "$TF" ] then - if [ -z "$found" ]; then echo ; found="yes"; fi - $PRINTF "\tother: ${OF}\n\tthis : ${TF}\n" + if [ "`echo $OF | $GREP -c 'Zip archive data'`" -gt 0 ] \ + && [ "`echo $TF | $GREP -c 'Zip archive data'`" -gt 0 ] + then + # the way we produce zip-files make it so that directories are stored in + # old file but not in new (only files with full-path) this makes file + # report them as different + continue + else + if [ -z "$found" ]; then echo ; found="yes"; fi + $PRINTF "\tother: ${OF}\n\tthis : ${TF}\n" + fi fi done - if [ -z "$found" ]; then + if [ -z "$found" ]; then echo "Identical!" else REGRESSIONS=true @@ -296,12 +296,13 @@ compare_general_files() { THIS_DIR=$1 OTHER_DIR=$2 WORK_DIR=$3 - + GENERAL_FILES=$(cd $THIS_DIR && $FIND . -type f ! -name "*.so" ! -name "*.jar" ! -name "*.zip" \ ! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" ! -name "*.jimage" \ - ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \ + ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" ! -name "*.cpl" \ ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \ ! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \ + ! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" ! -name "JavaUpdater" \ | $GREP -v "./bin/" | $SORT | $FILTER) echo General files... @@ -377,7 +378,7 @@ compare_zip_file() { THIS_SUFFIX="${THIS_ZIP##*.}" OTHER_SUFFIX="${OTHER_ZIP##*.}" if [ "$THIS_SUFFIX" != "$OTHER_SUFFIX" ]; then - echo The files do not have the same suffix type! + echo "The files do not have the same suffix type! ($THIS_SUFFIX != $OTHER_SUFFIX)" return 2 fi @@ -389,7 +390,7 @@ compare_zip_file() { fi # Not quite identical, the might still contain the same data. # Unpack the jar/zip files in temp dirs - + THIS_UNZIPDIR=$WORK_DIR/$ZIP_FILE.this OTHER_UNZIPDIR=$WORK_DIR/$ZIP_FILE.other $RM -rf $THIS_UNZIPDIR $OTHER_UNZIPDIR @@ -464,9 +465,9 @@ compare_zip_file() { $RM -f $WORK_DIR/$ZIP_FILE.diffs for file in $DIFFING_FILES; do - if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then + if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then diff_text $OTHER_UNZIPDIR/$file $THIS_UNZIPDIR/$file >> $WORK_DIR/$ZIP_FILE.diffs - fi + fi done if [ -s "$WORK_DIR/$ZIP_FILE.diffs" ]; then @@ -573,6 +574,10 @@ compare_bin_file() { $MKDIR -p $FILE_WORK_DIR + # Make soft links to original files from work dir to facilitate debugging + $LN -f -s $THIS_FILE $WORK_FILE_BASE.this + $LN -f -s $OTHER_FILE $WORK_FILE_BASE.other + ORIG_THIS_FILE="$THIS_FILE" ORIG_OTHER_FILE="$OTHER_FILE" @@ -589,50 +594,51 @@ compare_bin_file() { fi if [ "$OPENJDK_TARGET_OS" = "windows" ]; then - unset _NT_SYMBOL_PATH - # On windows we need to unzip the debug symbols, if present - OTHER_FILE_BASE=${OTHER_FILE/.dll/} - OTHER_FILE_BASE=${OTHER_FILE_BASE/.exe/} - DIZ_NAME=$(basename $OTHER_FILE_BASE).diz + unset _NT_SYMBOL_PATH + # On windows we need to unzip the debug symbols, if present + OTHER_FILE_BASE=${OTHER_FILE/.dll/} + OTHER_FILE_BASE=${OTHER_FILE_BASE/.exe/} + OTHER_FILE_BASE=${OTHER_FILE_BASE/.cpl/} + DIZ_NAME=$(basename $OTHER_FILE_BASE).diz # java.exe and java.dll diz files will have the same name. Have to - # make sure java.exe gets the right one. This is only needed for - # OTHER since in the new build, all pdb files are left around. - if [ "$NAME" = "java.exe" ] && [ -f "$OTHER/tmp/java/java/obj64/java.diz" ]; then - OTHER_DIZ_FILE="$OTHER/tmp/java/java/obj64/java.diz" - elif [ -f "${OTHER_FILE_BASE}.diz" ]; then - OTHER_DIZ_FILE=${OTHER_FILE_BASE}.diz - else + # make sure java.exe gets the right one. This is only needed for + # OTHER since in the new build, all pdb files are left around. + if [ "$NAME" = "java.exe" ] && [ -f "$OTHER/tmp/java/java/obj64/java.diz" ]; then + OTHER_DIZ_FILE="$OTHER/tmp/java/java/obj64/java.diz" + elif [ -f "${OTHER_FILE_BASE}.diz" ]; then + OTHER_DIZ_FILE=${OTHER_FILE_BASE}.diz + else # Some files, jli.dll, appears twice in the image but only one of - # thme has a diz file next to it. - OTHER_DIZ_FILE="$($FIND $OTHER_DIR -name $DIZ_NAME | $SED 1q)" - if [ ! -f "$OTHER_DIZ_FILE" ]; then - # As a last resort, look for diz file in the whole build output - # dir. - OTHER_DIZ_FILE="$($FIND $OTHER -name $DIZ_NAME | $SED 1q)" - fi - fi - if [ -n "$OTHER_DIZ_FILE" ]; then - $MKDIR -p $FILE_WORK_DIR/other - (cd $FILE_WORK_DIR/other ; $UNARCHIVE -o $OTHER_DIZ_FILE) - export _NT_SYMBOL_PATH="$FILE_WORK_DIR/other" - fi - THIS_FILE_BASE=${THIS_FILE/.dll/} - THIS_FILE_BASE=${THIS_FILE_BASE/.exe/} - if [ -f "${THIS_FILE/.dll/}.diz" ]; then - THIS_DIZ_FILE=${THIS_FILE/.dll/}.diz - else - THIS_DIZ_FILE="$($FIND $THIS_DIR -name $DIZ_NAME | $SED 1q)" - if [ ! -f "$THIS_DIZ_FILE" ]; then - # As a last resort, look for diz file in the whole build output - # dir. - THIS_DIZ_FILE="$($FIND $THIS -name $DIZ_NAME | $SED 1q)" - fi - fi - if [ -n "$THIS_DIZ_FILE" ]; then - $MKDIR -p $FILE_WORK_DIR/this - (cd $FILE_WORK_DIR/this ; $UNARCHIVE -o $THIS_DIZ_FILE) - export _NT_SYMBOL_PATH="$_NT_SYMBOL_PATH;$FILE_WORK_DIR/this" - fi + # thme has a diz file next to it. + OTHER_DIZ_FILE="$($FIND $OTHER_DIR -name $DIZ_NAME | $SED 1q)" + if [ ! -f "$OTHER_DIZ_FILE" ]; then + # As a last resort, look for diz file in the whole build output + # dir. + OTHER_DIZ_FILE="$($FIND $OTHER -name $DIZ_NAME | $SED 1q)" + fi + fi + if [ -n "$OTHER_DIZ_FILE" ]; then + $MKDIR -p $FILE_WORK_DIR/other + (cd $FILE_WORK_DIR/other ; $UNARCHIVE -o $OTHER_DIZ_FILE) + export _NT_SYMBOL_PATH="$FILE_WORK_DIR/other" + fi + THIS_FILE_BASE=${THIS_FILE/.dll/} + THIS_FILE_BASE=${THIS_FILE_BASE/.exe/} + if [ -f "${THIS_FILE/.dll/}.diz" ]; then + THIS_DIZ_FILE=${THIS_FILE/.dll/}.diz + else + THIS_DIZ_FILE="$($FIND $THIS_DIR -name $DIZ_NAME | $SED 1q)" + if [ ! -f "$THIS_DIZ_FILE" ]; then + # As a last resort, look for diz file in the whole build output + # dir. + THIS_DIZ_FILE="$($FIND $THIS -name $DIZ_NAME | $SED 1q)" + fi + fi + if [ -n "$THIS_DIZ_FILE" ]; then + $MKDIR -p $FILE_WORK_DIR/this + (cd $FILE_WORK_DIR/this ; $UNARCHIVE -o $THIS_DIZ_FILE) + export _NT_SYMBOL_PATH="$_NT_SYMBOL_PATH;$FILE_WORK_DIR/this" + fi fi if [ -z "$SKIP_BIN_DIFF" ]; then @@ -670,19 +676,19 @@ compare_bin_file() { DIFF_SIZE_REL=$($EXPR $THIS_SIZE \* 100 / $OTHER_SIZE) SIZE_MSG=$($PRINTF "%3d%% %4d" $DIFF_SIZE_REL $DIFF_SIZE_NUM) if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] \ - && [ "$DIFF_SIZE_REL" -lt 102 ]; then + && [ "$DIFF_SIZE_REL" -lt 102 ]; then SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= elif [ "$OPENJDK_TARGET_OS" = "windows" ] \ - && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ - && [ "$DIFF_SIZE_NUM" = 512 ]; then - # On windows, size of binaries increase in 512 increments. + && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ + && [ "$DIFF_SIZE_NUM" = 512 ]; then + # On windows, size of binaries increase in 512 increments. SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= elif [ "$OPENJDK_TARGET_OS" = "windows" ] \ - && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ - && [ "$DIFF_SIZE_NUM" = -512 ]; then - # On windows, size of binaries increase in 512 increments. + && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ + && [ "$DIFF_SIZE_NUM" = -512 ]; then + # On windows, size of binaries increase in 512 increments. SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= else @@ -717,18 +723,18 @@ compare_bin_file() { if [ "$OPENJDK_TARGET_OS" = "windows" ]; then # The output from dumpbin on windows differs depending on if the debug symbol # files are still around at the location the binary is pointing too. Need - # to filter out that extra information. - $DUMPBIN -exports $OTHER_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $DUMPBIN -exports $THIS_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + # to filter out that extra information. + $DUMPBIN -exports $OTHER_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $DUMPBIN -exports $THIS_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this elif [ "$OPENJDK_TARGET_OS" = "solaris" ]; then # Some symbols get seemingly random 15 character prefixes. Filter them out. $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this else - $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this fi - + LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff if [ -s $WORK_FILE_BASE.symbols.diff ]; then SYM_MSG=" diff " @@ -741,7 +747,7 @@ compare_bin_file() { SYM_MSG=" $SYM_MSG " fi else - SYM_MSG="($SYM_MSG)" + SYM_MSG="($SYM_MSG)" DIFF_SYM= fi else @@ -754,48 +760,48 @@ compare_bin_file() { # Check dependencies if [ -n "$LDD_CMD" ]; then - (cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME 2>/dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq) - (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2 $WORK_FILE_BASE.deps.this.uniq) - (cd $FILE_WORK_DIR && $RM -f $NAME) - - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq - - if [ -s $WORK_FILE_BASE.deps.diff ]; then + (cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME 2>/dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq) + (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2 $WORK_FILE_BASE.deps.this.uniq) + (cd $FILE_WORK_DIR && $RM -f $NAME) + + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq + + if [ -s $WORK_FILE_BASE.deps.diff ]; then if [ -s $WORK_FILE_BASE.deps.diff.uniq ]; then - DEP_MSG=" diff " + DEP_MSG=" diff " else - DEP_MSG=" redun " + DEP_MSG=" redun " fi if [[ "$ACCEPTED_DEP_DIFF" != *"$BIN_FILE"* ]]; then - DIFF_DEP=true - if [[ "$KNOWN_DEP_DIFF" != *"$BIN_FILE"* ]]; then + DIFF_DEP=true + if [[ "$KNOWN_DEP_DIFF" != *"$BIN_FILE"* ]]; then DEP_MSG="*$DEP_MSG*" REGRESSIONS=true - else + else DEP_MSG=" $DEP_MSG " - fi + fi else - DEP_MSG="($DEP_MSG)" - DIFF_DEP= + DEP_MSG="($DEP_MSG)" + DIFF_DEP= fi - else - DEP_MSG=" " - DIFF_DEP= + else + DEP_MSG=" " + DIFF_DEP= if [[ "$KNOWN_DEP_DIFF $ACCEPTED_DEP_DIFF" = *"$BIN_FILE"* ]]; then DEP_MSG=" ! " fi - fi + fi else - DEP_MSG=" - " + DEP_MSG=" - " fi - + # Compare fulldump output if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then $FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1 $FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1 LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff - + if [ -s $WORK_FILE_BASE.fulldump.diff ]; then ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}') ELF_MSG=$($PRINTF "%8d" $ELF_DIFF_SIZE) @@ -822,14 +828,17 @@ compare_bin_file() { # Compare disassemble output if [ -n "$DIS_CMD" ] && [ -z "$SKIP_DIS_DIFF" ]; then - if [ -z "$DIS_DIFF_FILTER" ]; then - DIS_DIFF_FILTER="$CAT" - fi - $DIS_CMD $OTHER_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.other 2>&1 - $DIS_CMD $THIS_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.this 2>&1 - + # By default we filter out differences that include references to symbols. + # To get a raw diff with the complete disassembly, set + # DIS_DIFF_FILTER="$CAT" + if [ -z "$DIS_DIFF_FILTER" ]; then + DIS_DIFF_FILTER="$GREP -v ' # .* <.*>$'" + fi + $DIS_CMD $OTHER_FILE | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.other 2>&1 + $DIS_CMD $THIS_FILE | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 + LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff - + if [ -s $WORK_FILE_BASE.dis.diff ]; then DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}') DIS_MSG=$($PRINTF "%8d" $DIS_DIFF_SIZE) @@ -907,7 +916,9 @@ compare_all_libs() { OTHER_DIR=$2 WORK_DIR=$3 - LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' -o -name 'JavaControlPanel' \) | $SORT | $FILTER) + LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' \ + -o -name '*.dll' -o -name '*.obj' -o -name '*.o' \ + -o -name '*.cpl' \) | $SORT | $FILTER) if [ -n "$LIBS" ]; then echo Libraries... @@ -967,7 +978,7 @@ COMPARE_ROOT=/tmp/cimages.$USER $MKDIR -p $COMPARE_ROOT if [ "$OPENJDK_TARGET_OS" = "windows" ]; then if [ "$(uname -o)" = "Cygwin" ]; then - COMPARE_ROOT=$(cygpath -msa $COMPARE_ROOT) + COMPARE_ROOT=$(cygpath -msa $COMPARE_ROOT) fi fi @@ -1091,7 +1102,7 @@ while [ -n "$1" ]; do CMP_JARS=true CMP_LIBS=true CMP_EXECS=true - + if [ -z "$FILTER" ]; then FILTER="$GREP" fi @@ -1177,8 +1188,8 @@ if [ "$SKIP_DEFAULT" != "true" ]; then OTHER_J2RE="$OTHER/images/jre" echo "Selecting jdk images for compare" else - echo "No common images found." - exit 1 + echo "No common images found." + exit 1 fi if [ -d "$THIS/images/jdk-bundle" ] && [ -d "$OTHER/images/jdk-bundle" ]; then @@ -1189,6 +1200,17 @@ if [ "$SKIP_DEFAULT" != "true" ]; then echo "Also comparing macosx bundles" fi + if [ -d "$THIS/deploy" ] && [ -d "$OTHER/deploy" ]; then + THIS_DEPLOY_BUNDLE_DIR="$THIS/deploy/dist/installer/bundles" + OTHER_DEPLOY_BUNDLE_DIR="$OTHER/deploy/bundles" + echo "Also comparing deploy/bundles" + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then + THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/JavaAppletPlugin.plugin" + OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/JavaAppletPlugin.plugin" + echo "Also comparing JavaAppletPlugin" + fi + fi + if [ -d "$OTHER/images" ]; then OTHER_SEC_DIR="$OTHER/images" else @@ -1212,7 +1234,7 @@ if [ "$SKIP_DEFAULT" != "true" ]; then if [ -d "$THIS/docs" ] && [ -d "$OTHER/docs" ]; then THIS_DOCS="$THIS/docs" OTHER_DOCS="$OTHER/docs" - echo "Also comparing docs" + echo "Also comparing docs" else echo "WARNING! Docs haven't been built and won't be compared." fi @@ -1227,7 +1249,7 @@ if [ "$CMP_NAMES" = "true" ]; then compare_dirs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk echo -n "J2RE " compare_dirs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re - + echo -n "J2SDK " compare_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk echo -n "J2RE " @@ -1238,7 +1260,7 @@ if [ "$CMP_NAMES" = "true" ]; then compare_dirs $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle echo -n "J2RE Bundle " compare_dirs $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle - + echo -n "J2SDK Bundle " compare_files $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle echo -n "J2RE Bundle " @@ -1254,6 +1276,12 @@ if [ "$CMP_NAMES" = "true" ]; then compare_dirs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir compare_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_dirs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + echo -n "JavaAppletPlugin " + compare_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_PERMS" = "true" ]; then @@ -1266,6 +1294,10 @@ if [ "$CMP_PERMS" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_TYPES" = "true" ]; then @@ -1284,6 +1316,10 @@ if [ "$CMP_TYPES" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_GENERAL" = "true" ]; then @@ -1306,6 +1342,10 @@ if [ "$CMP_GENERAL" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_general_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_general_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_ZIPS" = "true" ]; then @@ -1333,6 +1373,12 @@ if [ "$CMP_ZIPS" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_zip_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_BUNDLE_DIR" ] && [ -n "$OTHER_DEPLOY_BUNDLE_DIR" ]; then + compare_all_zip_files $THIS_DEPLOY_BUNDLE_DIR $OTHER_DEPLOY_BUNDLE_DIR $COMPARE_ROOT/deploy-bundle + fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + compare_all_zip_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_JARS" = "true" ]; then @@ -1342,6 +1388,9 @@ if [ "$CMP_JARS" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_jar_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + compare_all_jar_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_LIBS" = "true" ]; then @@ -1356,15 +1405,27 @@ if [ "$CMP_LIBS" = "true" ]; then if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_EXECS" = "true" ]; then if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then compare_all_execs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then + echo -n "J2RE " + compare_all_execs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re + fi fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi echo diff --git a/make/Images.gmk b/make/Images.gmk index 93a73a5b1b7..20c5e1011de 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -29,7 +29,7 @@ include $(SPEC) include MakeBase.gmk TOOL_TARGETS := -JDK_TARGETS := +JDK_TARGETS := JRE_TARGETS := # Hook to include the corresponding custom file, if present. @@ -69,7 +69,7 @@ JDK_COMPACT3_MODULES := java.compact3 java.smartcardio jdk.httpserver jdk.naming jdk.naming.rmi jdk.sctp jdk.security.auth # Replacing double-comma with a single comma is to workaround the issue -# with some version of make on windows that doesn't substitute spaces +# with some version of make on windows that doesn't substitute spaces # with one comma properly as with make 4.0 define SubstComma $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) diff --git a/make/MakeHelpers.gmk b/make/MakeHelpers.gmk index 359fb7ee2ea..8441e95d356 100644 --- a/make/MakeHelpers.gmk +++ b/make/MakeHelpers.gmk @@ -353,7 +353,7 @@ MAKE_MAKEDIR_LIST := make # Helper macro for DeclareRecipesForPhase # Declare a recipe for calling the module and phase specific makefile. # If there are multiple makefiles to call, create a rule for each topdir -# that contains a makefile with the target $module-$suffix-$repodir, +# that contains a makefile with the target $module-$suffix-$repodir, # (i.e: java.base-gensrc-jdk) # Normally there is only one makefile, and the target will just be # $module-$suffix diff --git a/make/ModuleWrapper.gmk b/make/ModuleWrapper.gmk index 40d2c837b97..ba8cfab8aa5 100644 --- a/make/ModuleWrapper.gmk +++ b/make/ModuleWrapper.gmk @@ -26,7 +26,7 @@ ################################################################################ # This makefile is called from Main.gmk, through a macro in MakeHelpers.gmk # and wraps calls to makefiles for specific modules and build phases. Having -# this wrapper reduces the need for boilerplate code. It also provides +# this wrapper reduces the need for boilerplate code. It also provides # opportunity for automatic copying of files to an interim exploded runnable # image. From 963ea242c9fad06a2f0c50346fd2f9419f9528ee Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 15 Jan 2015 15:40:56 +0100 Subject: [PATCH 57/72] 8069063: More merge errors following JDK-8049367 Reviewed-by: erikj --- make/common/NativeCompilation.gmk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index d8ca38090df..9088a61e645 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -577,7 +577,7 @@ define SetupNativeCompilationInner $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_REAL_MAPFILE) \ $$($1_DEBUGINFO_EXTRA_DEPS) - $$(call LINKING_MSG,$$($1_BASENAME)) + $(ECHO) $(LOG_INFO) "Linking $$($1_BASENAME)" $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ $(LD_OUT_OPTION)$$@ \ $$($1_EXPECTED_OBJS) $$($1_RES) \ @@ -605,7 +605,7 @@ define SetupNativeCompilationInner $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_GEN_MANIFEST) \ $$($1_DEBUGINFO_EXTRA_DEPS) - $$(call LINKING_EXE_MSG,$$($1_BASENAME)) + $(ECHO) $(LOG_INFO) "Linking executable $$($1_BASENAME)" $$($1_LDEXE) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ $(EXE_OUT_OPTION)$$($1_TARGET) \ $$($1_EXPECTED_OBJS) $$($1_RES) \ From 721b7a43be891b27abee56b94bcfaf9ba5927331 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 15 Jan 2015 15:43:28 +0100 Subject: [PATCH 58/72] 8069057: Make sure configure is run by bash Reviewed-by: erikj --- common/autoconf/configure | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/autoconf/configure b/common/autoconf/configure index b49e03e7fad..b6a38a307e3 100644 --- a/common/autoconf/configure +++ b/common/autoconf/configure @@ -36,6 +36,13 @@ else shift fi +if test "x$BASH" = x; then + echo "Error: This script must be run using bash." 1>&2 + exit 1 +fi +# Force autoconf to use bash +export CONFIG_SHELL=$BASH + conf_script_dir="$TOPDIR/common/autoconf" if [ "$CUSTOM_CONFIG_DIR" = "" ]; then From cd582fa380a31a9220ce18606fa2fc255d39fbdb Mon Sep 17 00:00:00 2001 From: Michail Chernov Date: Thu, 15 Jan 2015 19:16:17 +0400 Subject: [PATCH 59/72] 8066122: CollectionUsageThreshold.java times out when run with -XX:+ExplicitGCInvokesConcurrent CollectionUsageThreshold.java hangs due to VM performs concurrent GC with -XX:+ExplicitGCInvokesConcurrent flag, as result - notification is not received. Excluded test execution with -XX:+ExplicitGCInvokesConcurrent. Reviewed-by: dfazunen, tschatzl --- .../lang/management/MemoryMXBean/CollectionUsageThreshold.java | 3 ++- jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java index 64224d23306..74e06e6aa6e 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * * @library /lib/testlibrary/ * @build jdk.testlibrary.* CollectionUsageThreshold MemoryUtil RunUtil + * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" * @run main/timeout=300 CollectionUsageThreshold */ diff --git a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java index 6bf2e8f1ee2..e0d30f0e3c8 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java @@ -32,6 +32,7 @@ * * @library /lib/testlibrary/ * @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil + * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" * @run main/timeout=600 LowMemoryTest */ From 00b2f7005de70a7cc9c6ff3bcb6a719fc36bd088 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 15 Jan 2015 17:05:06 +0000 Subject: [PATCH 60/72] 8042581: Intermittent failure in java/net/DatagramSocket/InheritHandle.java Reviewed-by: alanb, chegar --- .../net/DatagramSocket/InheritHandle.java | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/jdk/test/java/net/DatagramSocket/InheritHandle.java b/jdk/test/java/net/DatagramSocket/InheritHandle.java index b351177644d..80360e7b96c 100644 --- a/jdk/test/java/net/DatagramSocket/InheritHandle.java +++ b/jdk/test/java/net/DatagramSocket/InheritHandle.java @@ -22,27 +22,51 @@ */ /* @test - * @bug 4945514 + * @bug 4945514 8042581 * @summary DatagramSocket should make handle not inherited */ -import java.net.*; +import java.net.BindException; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; public class InheritHandle { + private static final long SLEEPTIME_MS = 1000L; + public static void main(String[] args) throws Exception { - DatagramSocket sock = new DatagramSocket (0); - sock.setReuseAddress(true); - int port = sock.getLocalPort(); + int port; + try (DatagramSocket sock = new DatagramSocket(0);) { + sock.setReuseAddress(true); + port = sock.getLocalPort(); - /** - * spawn a child to check whether handle passed to it or not; - * it shouldn't - */ - Runtime.getRuntime().exec ("sleep 10"); + /** + * spawn a child to check whether handle passed to it or not; it + * shouldn't + */ + Runtime.getRuntime().exec("sleep 10"); + } - sock.close(); - sock = new DatagramSocket (null); - sock.setReuseAddress(true); - sock.bind(new InetSocketAddress(port)); + try (DatagramSocket sock = new DatagramSocket(null);) { + sock.setReuseAddress(true); + int retries = 0; + boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + InetSocketAddress addr = new InetSocketAddress(port); + while (true) { + try { + sock.bind(addr); + break; + } catch (BindException e) { + if (isWindows && retries++ < 5) { + Thread.sleep(SLEEPTIME_MS); + System.out.println("BindException \"" + e.getMessage() + "\", retrying..."); + continue; + } else { + throw e; + } + } + } + + } } } + From f46b3d442f5869aa47e360b472b2029a5607225d Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Thu, 15 Jan 2015 17:57:52 +0000 Subject: [PATCH 61/72] 8059009: LDAPCertStore fails to retrieve CRL after LDAP server closes idle connection Reviewed-by: vinnie --- .../classes/com/sun/jndi/ldap/LdapCtx.java | 7 ++-- .../provider/certpath/ldap/LDAPCertStore.java | 34 ++++++++++++++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java index d8bf38be60a..f89faab4138 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -224,6 +224,7 @@ final public class LdapCtx extends ComponentDirContext String hostname = null; // host name of server (no brackets // for IPv6 literals) LdapClient clnt = null; // connection handle + private boolean reconnect = false; // indicates that re-connect requested Hashtable envprops = null; // environment properties of context int handleReferrals = DEFAULT_REFERRAL_MODE; // how referral is handled boolean hasLdapsScheme = false; // true if the context was created @@ -2663,6 +2664,7 @@ final public class LdapCtx extends ComponentDirContext } sharable = false; // can't share with existing contexts + reconnect = true; ensureOpen(); // open or reauthenticated } @@ -2739,7 +2741,7 @@ final public class LdapCtx extends ComponentDirContext try { boolean initial = (clnt == null); - if (initial) { + if (initial || reconnect) { ldapVersion = (ver != null) ? Integer.parseInt(ver) : DEFAULT_LDAP_VERSION; @@ -2767,6 +2769,7 @@ final public class LdapCtx extends ComponentDirContext // Required for SASL client identity envprops); + reconnect = false; /** * Pooled connections are preauthenticated; diff --git a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java index 05499ead984..3a050d6b55e 100644 --- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java +++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java @@ -37,12 +37,13 @@ import javax.naming.NameNotFoundException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; import java.security.*; import java.security.cert.Certificate; import java.security.cert.*; +import javax.naming.CommunicationException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; import javax.security.auth.x500.X500Principal; import sun.misc.HexDumpEncoder; @@ -160,7 +161,12 @@ public final class LDAPCertStore extends CertStoreSpi { /** * The JNDI directory context. */ - private DirContext ctx; + private LdapContext ctx; + + /** + * Flag indicating that communication error occurred. + */ + private boolean communicationError = false; /** * Flag indicating whether we should prefetch CRLs. @@ -218,6 +224,11 @@ public final class LDAPCertStore extends CertStoreSpi { certStoreCache = Cache.newSoftMemoryCache(185); static synchronized CertStore getInstance(LDAPCertStoreParameters params) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { + // if necessary, convert params to SunLDAPCertStoreParameters because + // LDAPCertStoreParameters does not override equals() and hashCode() + if (! (params instanceof SunLDAPCertStoreParameters)) { + params = new SunLDAPCertStoreParameters(params.getServerName(), params.getPort()); + } CertStore lcs = certStoreCache.get(params); if (lcs == null) { lcs = CertStore.getInstance("LDAP", params); @@ -256,7 +267,7 @@ public final class LDAPCertStore extends CertStoreSpi { } try { - ctx = new InitialDirContext(env); + ctx = new InitialLdapContext(env, null); /* * By default, follow referrals unless application has * overridden property in an application resource file. @@ -369,8 +380,17 @@ public final class LDAPCertStore extends CertStoreSpi { valueMap = new HashMap<>(8); String[] attrIds = requestedAttributes.toArray(STRING0); Attributes attrs; + + if (communicationError) { + ctx.reconnect(null); + communicationError = false; + } + try { attrs = ctx.getAttributes(name, attrIds); + } catch (CommunicationException ce) { + communicationError = true; + throw ce; } catch (NameNotFoundException e) { // name does not exist on this LDAP server // treat same as not attributes found @@ -884,7 +904,12 @@ public final class LDAPCertStore extends CertStoreSpi { SunLDAPCertStoreParameters() { super(); } + @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof LDAPCertStoreParameters)) { return false; } @@ -892,6 +917,7 @@ public final class LDAPCertStore extends CertStoreSpi { return (getPort() == params.getPort() && getServerName().equalsIgnoreCase(params.getServerName())); } + @Override public int hashCode() { if (hashCode == 0) { int result = 17; From 9d14d4b1e74a704dc20258fb5022a87110eea161 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:36 -0800 Subject: [PATCH 62/72] Added tag jdk9-b46 for changeset 2602be4290e7 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 0ad3d644f11..2539f7e2c81 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -288,3 +288,4 @@ f7c11da0b0481d49cc7a65a453336c108191e821 jdk9-b42 02ee8c65622e8bd97496d584e22fc7dcf0edc4ae jdk9-b43 8994f5d87b3bb5e8d317d4e8ccb326da1a73684a jdk9-b44 3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45 +12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46 From af90d9fe8a172384256a051df1cd556f39caf69e Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:37 -0800 Subject: [PATCH 63/72] Added tag jdk9-b46 for changeset 87aeabf7ffa2 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 859c412f8a7..b7b87c5d34e 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -288,3 +288,4 @@ e27c725d6c9d155667b35255f442d4ceb8c3c084 jdk9-b40 9645e35616b60c5c07b4fdf11a132afc8081dfa8 jdk9-b43 1f57bd728c9e6865ccb9d43ccd80a1c11230a32f jdk9-b44 9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45 +326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46 From 17e982a08fd3de84f3e76b0833758f8c73c1f92f Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:39 -0800 Subject: [PATCH 64/72] Added tag jdk9-b46 for changeset a41296327b3d --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index b4e518b36eb..d53cf114653 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -448,3 +448,4 @@ c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38 65a9747147b8090037541040ba67156ec914db6a jdk9-b43 43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44 5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45 +a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46 From 7c78550130566b552db9f565ddf7de990f19bd76 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:42 -0800 Subject: [PATCH 65/72] Added tag jdk9-b46 for changeset b037890ea772 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index cf9a1867715..38503a0b86f 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -288,3 +288,4 @@ a12d347f84176200593999f4da91ae2bb86865b2 jdk9-b39 40b242363040229a05224fbc5dc203a3f46a8f8f jdk9-b43 0cb0844b58924d6086d2850c22087d06679d5eef jdk9-b44 0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45 +74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46 From 3e2e519ce8fffc0f18f708670f4805ec4adaac0e Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:48 -0800 Subject: [PATCH 66/72] Added tag jdk9-b46 for changeset 1548d75015bd --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 7a8ce5643e2..b3c46658a54 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -288,3 +288,4 @@ e336cbd8b15e959e70ed02f0f5e93fa76ebd4c07 jdk9-b41 8c6ad41974f9ab6c33d544b088648314963f2a50 jdk9-b43 8cc4dc300041eb70a7a40e4b2431a8f4d4965ea4 jdk9-b44 9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45 +efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46 From 3a01ee0832af4602650c05d01062a9a4866b5ea8 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 15 Jan 2015 13:09:53 -0800 Subject: [PATCH 67/72] Added tag jdk9-b46 for changeset 167aecd0161e --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 924fdc2e2ad..b31c41f7e17 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -279,3 +279,4 @@ dd7bbdf81a537106cfa9227d1a9a57849cb26b4d jdk9-b37 8ae8dff2a28f3b8831cce97ae0c7a957c5dc650a jdk9-b43 50ee576062726e536d1bb9a5eadd8fd4470128fc jdk9-b44 3c2bbeda038aef7061455fec604db7d8a342fac5 jdk9-b45 +2ecf0a617f0f9af1ffd278a0c70e76f1946ce773 jdk9-b46 From 163f2e001ee810013783af3aa80b884219be5877 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 15 Jan 2015 14:51:05 -0800 Subject: [PATCH 68/72] 8067099: Add deprecation lint warning to build of jdk repository Reviewed-by: erikj --- make/common/SetupJavaCompilers.gmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/make/common/SetupJavaCompilers.gmk b/make/common/SetupJavaCompilers.gmk index 395de38f6ce..91c37932d91 100644 --- a/make/common/SetupJavaCompilers.gmk +++ b/make/common/SetupJavaCompilers.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,9 @@ include JavaCompilation.gmk DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally -# To build with all warnings enabled, do the following: +# If warnings needs to be non-fatal for testing purposes use a command like: # make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" -JAVAC_WARNINGS := -Xlint:all,-deprecation -Werror +JAVAC_WARNINGS := -Xlint:all -Werror # The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools # and the interim javac, to be run by the boot jdk. From c0500545f76895294f79682d7578ea8da504103c Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 15 Jan 2015 16:45:02 -0800 Subject: [PATCH 69/72] 8069127: Suppress deprecation warnings in jdk.deploy.osx module Reviewed-by: wetmore, juh --- .../macosx/classes/apple/security/KeychainStore.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java index a2436e587e1..36f146b9ba7 100644 --- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java +++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -911,6 +911,7 @@ public final class KeychainStore extends KeyStoreSpi { return true; } + @SuppressWarnings("deprecation") private byte[] fetchPrivateKeyFromBag(byte[] privateKeyInfo) throws IOException, NoSuchAlgorithmException, CertificateException { byte[] returnValue = null; @@ -971,6 +972,7 @@ public final class KeychainStore extends KeyStoreSpi { return returnValue; } + @SuppressWarnings("deprecation") private byte[] extractKeyData(DerInputStream stream) throws IOException, NoSuchAlgorithmException, CertificateException { From 120cde915bd3b8406d65e37e214b52db68df014b Mon Sep 17 00:00:00 2001 From: Tristan Yan Date: Thu, 15 Jan 2015 19:10:56 -0800 Subject: [PATCH 70/72] 8051563: Update JAXP functional tests Reviewed-by: lancea, joehw --- .../xml/parsers/ptests/DBFNamespaceTest.java | 61 +- .../ptests/DocumentBuilderFactory01.java | 451 ---------- .../ptests/DocumentBuilderFactory02.java | 87 -- .../ptests/DocumentBuilderFactoryTest.java | 462 ++++++++++ .../parsers/ptests/DocumentBuilderImpl01.java | 106 ++- .../parsers/ptests/FactoryConfErrorTest.java | 15 +- .../xml/parsers/ptests/SAXParserFactTest.java | 202 ++--- .../xml/parsers/ptests/SAXParserTest.java | 811 +++++++++--------- .../xml/parsers/ptests/SAXParserTest02.java | 211 ++--- .../xml/parsers/ptests/SAXParserTest03.java | 76 +- ...OMResultTest01.java => DOMResultTest.java} | 60 +- .../transform/ptests/ErrorListenerTest.java | 9 +- ...AXSourceTest01.java => SAXSourceTest.java} | 57 +- .../xml/transform/ptests/SAXTFactoryTest.java | 423 +++++++++ .../transform/ptests/SAXTFactoryTest001.java | 91 -- .../transform/ptests/SAXTFactoryTest002.java | 95 -- .../transform/ptests/SAXTFactoryTest003.java | 102 --- .../transform/ptests/SAXTFactoryTest004.java | 65 -- .../transform/ptests/SAXTFactoryTest005.java | 104 --- .../transform/ptests/SAXTFactoryTest006.java | 97 --- .../transform/ptests/SAXTFactoryTest008.java | 91 -- .../transform/ptests/SAXTFactoryTest009.java | 93 -- .../transform/ptests/SAXTFactoryTest010.java | 91 -- .../transform/ptests/SAXTFactoryTest011.java | 103 --- .../transform/ptests/SAXTFactoryTest012.java | 93 -- .../transform/ptests/SAXTFactoryTest013.java | 94 -- ...esultTest01.java => StreamResultTest.java} | 9 +- .../transform/ptests/TfClearParamTest.java | 307 +++---- .../transform/ptests/TransformerExcpTest.java | 11 +- .../ptests/TransformerFactoryTest.java | 27 +- .../xml/transform/ptests/TransformerTest.java | 179 ++-- .../transform/ptests/TransformerTest02.java | 45 +- .../transform/ptests/TransformerTest03.java | 47 +- .../xml/transform/ptests/URIResolverTest.java | 189 ++-- .../ptests/othervm/TFCErrorTest.java | 15 +- .../xml/xpath/ptests/XPathExpressionTest.java | 316 +++---- .../xml/xpath/ptests/XPathFactoryTest.java | 56 +- .../ptests/XPathFunctionResolverTest.java | 26 +- .../javax/xml/xpath/ptests/XPathTest.java | 384 ++++----- .../org/xml/sax/ptests/AttrImplTest.java | 5 +- .../org/xml/sax/ptests/AttributesNSTest.java | 57 +- .../org/xml/sax/ptests/AttributesTest.java | 54 +- .../xml/sax/ptests/ContentHandlerTest.java | 51 +- .../xml/sax/ptests/DefaultHandlerTest.java | 61 +- .../org/xml/sax/ptests/EHFatalTest.java | 41 +- .../org/xml/sax/ptests/NSSupportTest.java | 5 +- .../org/xml/sax/ptests/NSTableTest.java | 161 ++++ .../org/xml/sax/ptests/NSTableTest01.java | 193 ----- .../org/xml/sax/ptests/ParserAdapterTest.java | 120 ++- .../org/xml/sax/ptests/ResolverTest.java | 36 +- .../xml/sax/ptests/SAXParserNSTableTest.java | 113 +-- .../org/xml/sax/ptests/XMLFilterCBTest.java | 58 +- .../org/xml/sax/ptests/XMLFilterTest.java | 147 ++-- .../xml/sax/ptests/XMLReaderAdapterTest.java | 58 +- .../xml/sax/ptests/XMLReaderFactoryTest.java | 12 +- .../xml/sax/ptests/XMLReaderNSTableTest.java | 96 +-- .../org/xml/sax/ptests/XMLReaderTest.java | 621 ++++++-------- .../test/auctionportal/AuctionController.java | 314 +++---- .../auctionportal/AuctionItemRepository.java | 467 ++++------ .../test/auctionportal/UserController.java | 296 +++---- .../javax/xml/parsers/ptests/MyCHandler.java} | 61 +- .../xml/parsers/ptests/MyErrorHandler.java | 88 ++ .../xml/parsers/ptests/ParserTestConst.java | 46 + .../transform/ptests/MyContentHandler.java | 2 +- .../ptests/TransformerTestConst.java | 36 +- .../xml/xpath/ptests/XPathTestConst.java | 22 +- .../jaxp/libs/jaxp/library/JAXPBaseTest.java | 138 +++ .../libs/jaxp/library/JAXPFileBaseTest.java | 105 +++ .../library/JAXPFileReadOnlyBaseTest.java | 55 ++ .../libs/jaxp/library/JAXPTestUtilities.java | 171 +++- .../jaxp/libs/jaxp/library/TestPolicy.java | 149 ++++ .../org/xml/sax/ptests/MyAttrCHandler.java | 2 +- .../xml/sax/ptests/MyNSContentHandler.java | 15 +- .../libs/org/xml/sax/ptests/SAXTestConst.java | 36 +- .../test/auctionportal/HiBidConstants.java | 35 +- .../test/auctionportal/MyDOMErrorHandler.java | 2 +- .../test/auctionportal/MyDOMOutput.java | 4 +- .../test/auctionportal/MyErrorHandler.java | 2 +- .../test/auctionportal/XInclHandler.java | 31 +- 79 files changed, 4393 insertions(+), 5334 deletions(-) delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java create mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java rename jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/{DOMResultTest01.java => DOMResultTest.java} (63%) rename jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/{SAXSourceTest01.java => SAXSourceTest.java} (65%) create mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest001.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest002.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest003.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest004.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest005.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest006.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest008.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest009.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest010.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest011.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest012.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest013.java rename jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/{StreamResultTest01.java => StreamResultTest.java} (92%) create mode 100644 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java delete mode 100644 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java rename jaxp/test/javax/xml/jaxp/{functional/javax/xml/parsers/ptests/TestUtils.java => libs/javax/xml/parsers/ptests/MyCHandler.java} (83%) create mode 100644 jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java create mode 100644 jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java create mode 100644 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java create mode 100644 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java create mode 100644 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java create mode 100644 jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java rename jaxp/test/javax/xml/jaxp/{functional => libs}/org/xml/sax/ptests/MyAttrCHandler.java (98%) rename jaxp/test/javax/xml/jaxp/{functional => libs}/org/xml/sax/ptests/MyNSContentHandler.java (94%) rename jaxp/test/javax/xml/jaxp/{functional => libs}/test/auctionportal/MyDOMErrorHandler.java (96%) rename jaxp/test/javax/xml/jaxp/{functional => libs}/test/auctionportal/MyDOMOutput.java (96%) rename jaxp/test/javax/xml/jaxp/{functional => libs}/test/auctionportal/MyErrorHandler.java (97%) rename jaxp/test/javax/xml/jaxp/{functional => libs}/test/auctionportal/XInclHandler.java (92%) diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java index 930ef818341..6c2f073342b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,64 +23,59 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; - import java.io.File; -import java.io.IOException; - import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; +import static javax.xml.parsers.ptests.ParserTestConst.GOLDEN_DIR; +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; - +import jaxp.library.JAXPFileBaseTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * This tests DocumentBuilderFactory for namespace processing and no-namespace * processing. */ -public class DBFNamespaceTest { +public class DBFNamespaceTest extends JAXPFileBaseTest { /** * Provide input for the cases that supporting namespace or not. + * @return a two-dimensional array contains factory, output file name and + * golden validate file name. */ @DataProvider(name = "input-provider") public Object[][] getInput() { DocumentBuilderFactory dbf1 = DocumentBuilderFactory.newInstance(); - String outputfile1 = USER_DIR + FILE_SEP + "dbfnstest01.out"; - String goldfile1 = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfnstest01GF.out"; + String outputfile1 = USER_DIR + "dbfnstest01.out"; + String goldfile1 = GOLDEN_DIR + "dbfnstest01GF.out"; DocumentBuilderFactory dbf2 = DocumentBuilderFactory.newInstance(); dbf2.setNamespaceAware(true); - String outputfile2 = USER_DIR + FILE_SEP + "dbfnstest02.out"; - String goldfile2 = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfnstest02GF.out"; + String outputfile2 = USER_DIR + "dbfnstest02.out"; + String goldfile2 = GOLDEN_DIR + "dbfnstest02GF.out"; return new Object[][] { { dbf1, outputfile1, goldfile1 }, { dbf2, outputfile2, goldfile2 } }; } /** * Test to parse and transform a document without supporting namespace and * with supporting namespace. + * @param dbf a Document Builder factory for creating document object. + * @param outputfile output file name. + * @param goldfile golden validate file name. + * @throws Exception If any errors occur. */ @Test(dataProvider = "input-provider") - public void testNamespaceTest(DocumentBuilderFactory dbf, String outputfile, String goldfile) { - try { - Document doc = dbf.newDocumentBuilder().parse(new File(TestUtils.XML_DIR, "namespace1.xml")); - dummyTransform(doc, outputfile); - assertTrue(compareWithGold(goldfile, outputfile)); - } catch (SAXException | IOException | ParserConfigurationException | TransformerFactoryConfigurationError | TransformerException e) { - failUnexpected(e); - } + public void testNamespaceTest(DocumentBuilderFactory dbf, String outputfile, + String goldfile) throws Exception { + Document doc = dbf.newDocumentBuilder().parse(new File(XML_DIR, "namespace1.xml")); + dummyTransform(doc, outputfile); + assertTrue(compareWithGold(goldfile, outputfile)); } /** @@ -89,16 +84,14 @@ public class DBFNamespaceTest { * not chosen, namespaceURI in callbacks should be an empty string otherwise * it should be namespaceURI. * - * @throws TransformerFactoryConfigurationError - * @throws TransformerException - * @throws IOException + * @throws Exception If any errors occur. */ - private void dummyTransform(Document document, String fileName) throws TransformerFactoryConfigurationError, TransformerException, IOException { + private void dummyTransform(Document document, String fileName) + throws Exception { DOMSource domSource = new DOMSource(document); - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - File file = new File(fileName); - System.out.println("The fileName is " + file.getAbsolutePath()); - transformer.transform(domSource, new SAXResult(MyCHandler.newInstance(file))); + try(MyCHandler chandler = MyCHandler.newInstance(new File(fileName))) { + TransformerFactory.newInstance().newTransformer(). + transform(domSource, new SAXResult(chandler)); + } } - } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java deleted file mode 100644 index fddfaaa89b1..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * This checks the methods of DocumentBuilderFactoryImpl - */ -public class DocumentBuilderFactory01 { - /** - * Testcase to test the default functionality of schema support method. - */ - @Test - public void testCheckSchemaSupport1() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - dbf.setNamespaceAware(true); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "test.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of schema support method. In - * this case the schema source property is set. - */ - @Test - public void testCheckSchemaSupport2() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - dbf.setNamespaceAware(true); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", new InputSource(new FileInputStream( - new File(TestUtils.XML_DIR, "test.xsd")))); - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "test1.xml")); - assertFalse(eh.errorOccured); - } catch (IllegalArgumentException | ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the default functionality of schema support method. In - * this case the schema source property is set. - */ - @Test - public void testCheckSchemaSupport3() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(true); - spf.setNamespaceAware(true); - SAXParser sp = spf.newSAXParser(); - sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", - new InputSource(new FileInputStream(new File(TestUtils.XML_DIR, "test.xsd")))); - DefaultHandler dh = new DefaultHandler(); - sp.parse(new File(TestUtils.XML_DIR, "test1.xml"), dh); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of newInstance method. To test - * the isCoalescing method and setCoalescing This checks to see if the CDATA - * and text nodes got combined In that case it will print "<xml>This - * is not parsed</xml> yet". - */ - @Test - public void testCheckDocumentBuilderFactory02() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setCoalescing(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory01.xml")); - Element e = (Element) doc.getElementsByTagName("html").item(0); - NodeList nl = e.getChildNodes(); - assertEquals(nl.item(0).getNodeValue().trim(), "This is not parsed yet"); - } catch (IOException | SAXException | ParserConfigurationException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the isIgnoringComments. By default it is false. - */ - @Test - public void testCheckDocumentBuilderFactory03() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - assertFalse(dbf.isIgnoringComments()); - } - - /** - * Testcase to test the isValidating. By default it is false, set it to true - * and then use a document which is not valid. It should throw a warning or - * an error at least. The test passes in case retval 0 is set in the error - * method . - */ - @Test - public void testCheckDocumentBuilderFactory04() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory05.xml")); - assertTrue(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setValidating. By default it is false, use a - * document which is not valid. It should not throw a warning or an error. - * The test passes in case the retval equals 1 . - */ - @Test - public void testCheckDocumentBuilderFactory16() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory05.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the setValidating. By default it is false, use a - * document which is valid. It should not throw a warning or an error. The - * test passes in case the retval equals 1. - */ - @Test - public void testCheckDocumentBuilderFactory17() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory04.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * To test the isExpandEntityReferences. By default it is true. - */ - @Test - public void testCheckDocumentBuilderFactory05() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertTrue(dbf.isExpandEntityReferences()); - assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of setValidating method. The - * xml file has a DTD which has namespaces defined. The parser takes care to - * check if the namespaces using elements and defined attributes are there - * or not. - */ - @Test - public void testCheckDocumentBuilderFactory06() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - MyErrorHandler eh = MyErrorHandler.newInstance(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory04.xml")); - assertTrue(doc instanceof Document); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the setExpandEntityReferences. - */ - @Test - public void testCheckDocumentBuilderFactory07() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setExpandEntityReferences(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertTrue(dbf.isExpandEntityReferences()); - assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setExpandEntityReferences. - */ - @Test - public void testCheckDocumentBuilderFactory08() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setExpandEntityReferences(false); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setIgnoringComments. By default it is set to false. - * explicitly setting it to false, it recognizes the comment which is in - * Element Node Hence the Element's child node is not null. - */ - @Test - public void testCheckDocumentBuilderFactory09() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setIgnoringComments(false); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertNotNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * This tests for the parse(InputSource). - */ - @Test - public void testCheckDocumentBuilderFactory10() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new InputSource(new BufferedReader(new FileReader(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))))); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse InputStream with SystemID as a second parameter. - */ - @Test - public void testCheckDocumentBuilderFactory11() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "dbf10import.xsl")), new File(TestUtils.XML_DIR).toURI() - .toASCIIString()); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse InputStream with empty SystemID as a second - * parameter. - */ - @Test - public void testCheckDocumentBuilderFactory12() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "dbf10import.xsl")), " "); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse(uri). - */ - @Test - public void testCheckDocumentBuilderFactory13() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR + FILE_SEP + "dbf10import.xsl").toURI().toASCIIString()); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse (uri) with empty string as parameter should - * throw Sax Exception. - * - * @throws SAXException - * If any parse errors occur. - */ - @Test(expectedExceptions = SAXException.class) - public void testCheckDocumentBuilderFactory14() throws SAXException { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.parse(""); - } catch (ParserConfigurationException | IOException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse (uri) with null uri as parameter should throw - * IllegalArgumentException. - * - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckDocumentBuilderFactory15() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - String uri = null; - docBuilder.parse(uri); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setIgnoringComments. By default it is set to false, - * setting this to true, It does not recognize the comment, Here the - * nodelist has a length 0 because the ignoring comments is true. - */ - @Test - public void testCheckIgnoringComments() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setIgnoringComments(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory08.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertEquals(nl.getLength(), 0); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the default behaviour of setIgnoringComments. By default - * it is set to false, this is similar to case 9 but not setIgnoringComments - * explicitly, it does not recognize the comment. - */ - @Test - public void testCheckIgnoringComments1() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertFalse(dbf.isIgnoringComments()); - assertNotNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java deleted file mode 100644 index 68722085ba2..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; - -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -/** - * This tests the setIgnoringElementWhitespace and setIgnoringComments of - * DocumentBuilderFactory - */ -public class DocumentBuilderFactory02 { - - /** - * This testcase tests for the isIgnoringElementContentWhitespace and the - * setIgnoringElementContentWhitespace. The xml file has all kinds of - * whitespace,tab and newline characters, it uses the MyNSContentHandler - * which does not invoke the characters callback when this - * setIgnoringElementContentWhitespace is set to true. - */ - @Test - public void testCheckElementContentWhitespace() { - try { - String goldFile = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfactory02GF.out"; - String outputFile = USER_DIR + FILE_SEP + "dbfactory02.out"; - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - assertFalse(dbf.isIgnoringElementContentWhitespace()); - dbf.setIgnoringElementContentWhitespace(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory06.xml")); - assertFalse(eh.errorOccured); - DOMSource domSource = new DOMSource(doc); - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); - SAXResult saxResult = new SAXResult(); - saxResult.setHandler(MyCHandler.newInstance(new File(outputFile))); - transformer.transform(domSource, saxResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) { - failUnexpected(e); - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java new file mode 100644 index 00000000000..28ef7b0f226 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.xml.parsers.ptests; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilePermission; +import java.io.FileReader; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import static javax.xml.parsers.ptests.ParserTestConst.GOLDEN_DIR; +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * This checks the methods of DocumentBuilderFactoryImpl. + */ +public class DocumentBuilderFactoryTest extends JAXPFileBaseTest { + /** + * Test the default functionality of schema support method. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport1() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + dbf.setNamespaceAware(true); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "test.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the default functionality of schema support method. In + * this case the schema source property is set. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport2() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "test.xsd"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + dbf.setNamespaceAware(true); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", + new InputSource(fis)); + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "test1.xml")); + assertFalse(eh.isErrorOccured()); + } + } + + /** + * Test the default functionality of schema support method. In + * this case the schema source property is set. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport3() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "test.xsd"))) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); + spf.setNamespaceAware(true); + SAXParser sp = spf.newSAXParser(); + sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", + new InputSource(fis)); + DefaultHandler dh = new DefaultHandler(); + // Not expect any unrecoverable error here. + sp.parse(new File(XML_DIR, "test1.xml"), dh); + } + } + + /** + * Test the default functionality of newInstance method. To test + * the isCoalescing method and setCoalescing This checks to see if the CDATA + * and text nodes got combined In that case it will print "<xml>This + * is not parsed</xml> yet". + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory02() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setCoalescing(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new File(XML_DIR, "DocumentBuilderFactory01.xml")); + Element e = (Element) doc.getElementsByTagName("html").item(0); + NodeList nl = e.getChildNodes(); + assertEquals(nl.getLength(), 1); + } + + /** + * Test the isIgnoringComments. By default it is false. + */ + @Test + public void testCheckDocumentBuilderFactory03() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + assertFalse(dbf.isIgnoringComments()); + } + + /** + * Test the isValidating. By default it is false, set it to true and then + * use a document which is not valid. It should throw a warning or + * an error at least. The test passes in case retval 0 is set in the error + * method . + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory04() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml")); + assertTrue(eh.isErrorOccured()); + } + + /** + * Test the setValidating. By default it is false, use a + * document which is not valid. It should not throw a warning or an error. + * The test passes in case the return value equals 1. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory16() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the setValidating. By default it is false, use a + * document which is valid. It should not throw a warning or an error. The + * test passes in case the return value equals 1. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory17() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the isExpandEntityReferences. By default it is true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory05() throws Exception { + try(FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertTrue(dbf.isExpandEntityReferences()); + assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); + } + } + + /** + * Test the default functionality of setValidating method. The + * XML file has a DTD which has namespaces defined. The parser takes care to + * check if the namespaces using elements and defined attributes are there + * or not. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory06() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + MyErrorHandler eh = MyErrorHandler.newInstance(); + db.setErrorHandler(eh); + Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml")); + assertTrue(doc instanceof Document); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the setExpandEntityReferences. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory07() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setExpandEntityReferences(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertTrue(dbf.isExpandEntityReferences()); + assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); + } + } + + /** + * Test the setExpandEntityReferences. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory08() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setExpandEntityReferences(false); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertNull(nl.item(0).getNodeValue()); + } + } + + /** + * Test the setIgnoringComments. By default it is set to false. + * explicitly setting it to false, it recognizes the comment which is in + * Element Node Hence the Element's child node is not null. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory09() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory07.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringComments(false); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertNotNull(nl.item(0).getNodeValue()); + } + } + + /** + * This tests for the parse(InputSource). + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory10() throws Exception { + try (BufferedReader br = new BufferedReader(new FileReader(new File( + XML_DIR, "DocumentBuilderFactory07.xml")))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new InputSource(br)); + assertNotNull(doc); + } + } + + /** + * This tests for the parse InputStream with SystemID as a second parameter. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory11() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "dbf10import.xsl"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis, new File(XML_DIR).toURI() + .toASCIIString()); + assertNotNull(doc); + } + } + + /** + * This tests for the parse InputStream with empty SystemID as a second + * parameter. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory12() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "dbf10import.xsl"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis, " "); + assertNotNull(doc); + } + } + + /** + * This tests for the parse(uri). + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory13() throws Exception { + // Accesing default working directory. + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir + "/*", "read")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new File(XML_DIR + "dbf10import.xsl") + .toURI().toASCIIString()); + assertNotNull(doc); + } + + /** + * This tests for the parse(uri) with empty string as parameter should + * throw Sax Exception. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = SAXException.class) + public void testCheckDocumentBuilderFactory14() throws Exception { + // Accesing default working directory. + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.parse(""); + } + + /** + * This tests for the parse (uri) with null uri as parameter should throw + * IllegalArgumentException. + * @throws Exception If any errors occur. + * + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testCheckDocumentBuilderFactory15() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + String uri = null; + docBuilder.parse(uri); + } + + /** + * Test the setIgnoringComments. By default it is set to false, + * setting this to true, It does not recognize the comment, Here the + * nodelist has a length 0 because the ignoring comments is true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckIgnoringComments() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory08.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringComments(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertEquals(nl.getLength(), 0); + } + } + + /** + * Test the default behaviour of setIgnoringComments. By default + * it is set to false, this is similar to case 9 but not setIgnoringComments + * explicitly, it does not recognize the comment. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckIgnoringComments1() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory07.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertFalse(dbf.isIgnoringComments()); + assertNotNull(nl.item(0).getNodeValue()); + } + } + + /** + * Test for the isIgnoringElementContentWhitespace and the + * setIgnoringElementContentWhitespace. The xml file has all kinds of + * whitespace,tab and newline characters, it uses the MyNSContentHandler + * which does not invoke the characters callback when this + * setIgnoringElementContentWhitespace is set to true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckElementContentWhitespace() throws Exception { + String goldFile = GOLDEN_DIR + "dbfactory02GF.out"; + String outputFile = USER_DIR + "dbfactory02.out"; + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + assertFalse(dbf.isIgnoringElementContentWhitespace()); + dbf.setIgnoringElementContentWhitespace(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory06.xml")); + assertFalse(eh.isErrorOccured()); + DOMSource domSource = new DOMSource(doc); + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); + SAXResult saxResult = new SAXResult(); + try(MyCHandler handler = MyCHandler.newInstance(new File(outputFile))) { + saxResult.setHandler(handler); + transformer.transform(domSource, saxResult); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java index d565748c37a..144df205131 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,33 +24,32 @@ package javax.xml.parsers.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; - import java.io.File; import java.io.FileInputStream; -import java.io.IOException; - +import java.io.FilePermission; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * This checks for the methods of DocumentBuilder */ -public class DocumentBuilderImpl01 implements EntityResolver { - +public class DocumentBuilderImpl01 extends JAXPFileReadOnlyBaseTest + implements EntityResolver { /** * Provide DocumentBuilder. * - * @throws ParserConfigurationException + * @return data provider has single DocumentBuilder. + * @throws ParserConfigurationException if a DocumentBuilder cannot be + * created which satisfies the configuration requested. */ @DataProvider(name = "builder-provider") public Object[][] getBuilder() throws ParserConfigurationException { @@ -60,17 +59,18 @@ public class DocumentBuilderImpl01 implements EntityResolver { } /** - * Testcase to test the default functionality of isValidation method. Expect + * Test the default functionality of isValidation method. Expect * to return false because not setting the validation. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl01(DocumentBuilder docBuilder) { assertFalse(docBuilder.isValidating()); - } /** - * Testcase to test the default functionality of isNamespaceAware method. + * Test the default functionality of isNamespaceAware method. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl02(DocumentBuilder docBuilder) { @@ -78,51 +78,71 @@ public class DocumentBuilderImpl01 implements EntityResolver { } /** - * Testcase to test the parse(InputStream). + * Test the parse(InputStream). + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl04(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderImpl01.xml"))); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl04(DocumentBuilder docBuilder) + throws Exception { + try (FileInputStream fis = new FileInputStream(new File(XML_DIR, + "DocumentBuilderImpl01.xml"))) { + assertNotNull(docBuilder.parse(fis)); } } /** - * Testcase to test the parse(File). + * Test the parse(File). + * + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl05(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR, "DocumentBuilderImpl01.xml")); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl05(DocumentBuilder docBuilder) + throws Exception { + assertNotNull(docBuilder.parse(new File(XML_DIR, + "DocumentBuilderImpl01.xml"))); + } + + /** + * Test the parse(InputStream,systemId). + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl06(DocumentBuilder docBuilder) + throws Exception { + setPermissions(new FilePermission(XML_DIR + "../-", + "read")); + try (FileInputStream fis = new FileInputStream(new File(XML_DIR, + "DocumentBuilderImpl02.xml"))) { + assertNotNull(docBuilder.parse(fis, new File(XML_DIR).toURI() + .toASCIIString() + FILE_SEP)); } } /** - * Testcase to test the parse(InputStream,systemId). - */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl06(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderImpl02.xml")), new File(TestUtils.XML_DIR).toURI() - .toASCIIString() + FILE_SEP); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setEntityResolver. + * Test the setEntityResolver. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl07(DocumentBuilder docBuilder) { docBuilder.setEntityResolver(this); - resolveEntity("publicId", "http://www.myhost.com/today"); + assertNotNull(resolveEntity("publicId", "http://www.myhost.com/today")); } + /** + * Allow the application to resolve external entities. + * + * @param publicId The public identifier of the external entity + * being referenced, or null if none was supplied. + * @param systemId The system identifier of the external entity + * being referenced. + * @return An InputSource object describing the new input source, + * or null to request that the parser open a regular + * URI connection to the system identifier. + */ + @Override public InputSource resolveEntity(String publicId, String systemId) { if (systemId.equals("http://www.myhost.com/today")) return new InputSource(systemId); diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java index 947d6d8dd7d..88a66dd5506 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package javax.xml.parsers.ptests; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPBaseTest; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -35,7 +36,7 @@ import org.testng.annotations.Test; * Class containing the test cases for SAXParserFactory/DocumentBuilderFactory * newInstance methods. */ -public class FactoryConfErrorTest { +public class FactoryConfErrorTest extends JAXPBaseTest { /** * Set properties DocumentBuilderFactory and SAXParserFactory to invalid @@ -43,8 +44,8 @@ public class FactoryConfErrorTest { */ @BeforeTest public void setup() { - System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "xx"); - System.setProperty("javax.xml.parsers.SAXParserFactory", "xx"); + setSystemProperty("javax.xml.parsers.DocumentBuilderFactory", "xx"); + setSystemProperty("javax.xml.parsers.SAXParserFactory", "xx"); } /** @@ -53,8 +54,8 @@ public class FactoryConfErrorTest { */ @AfterTest public void cleanup() { - System.clearProperty("javax.xml.parsers.DocumentBuilderFactory"); - System.clearProperty("javax.xml.parsers.SAXParserFactory"); + setSystemProperty("javax.xml.parsers.DocumentBuilderFactory", null); + setSystemProperty("javax.xml.parsers.SAXParserFactory", null); } /** @@ -67,7 +68,7 @@ public class FactoryConfErrorTest { } /** - * To test exeception thrown if javax.xml.parsers.DocumentBuilderFactory is + * To test exception thrown if javax.xml.parsers.DocumentBuilderFactory is * invalid. */ @Test(expectedExceptions = FactoryConfigurationError.class) diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java index da87e006f58..8c84ed85cc0 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,24 +22,16 @@ */ package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import jaxp.library.JAXPBaseTest; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; /** - * Class containing the test cases for SAXParserFactory API + * Class containing the test cases for SAXParserFactory API. */ -public class SAXParserFactTest { +public class SAXParserFactTest extends JAXPBaseTest { private static final String NAMESPACES = "http://xml.org/sax/features/namespaces"; private static final String NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes"; @@ -49,20 +41,17 @@ public class SAXParserFactTest { private static final String EXTERNAL_P_ENTITIES = "http://xml.org/sax/features/external-parameter-entities"; /** - * Testcase to test if newSAXParser() method returns SAXParser. + * Test if newSAXParser() method returns SAXParser. + * @throws Exception If any errors occur. */ @Test - public void testParser01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxparser = spf.newSAXParser(); - } catch (ParserConfigurationException | SAXException e) { - failUnexpected(e); - } + public void testParser01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.newSAXParser(); } /** - * Testcase to test the default functionality (No validation) of the parser. + * Test the default functionality (No validation) of the parser. */ @Test public void testValidate01() { @@ -71,7 +60,7 @@ public class SAXParserFactTest { } /** - * Testcase to test the functionality of setValidating and isvalidating + * Test the functionality of setValidating and isvalidating * methods. */ @Test @@ -82,7 +71,7 @@ public class SAXParserFactTest { } /** - * Parser should not be namespaceaware by default. + * Parser should not be namespace-aware by default. */ @Test public void testNamespace01() { @@ -91,7 +80,7 @@ public class SAXParserFactTest { } /** - * Testcase to test the functionality of setNamespaceAware and + * Test the functionality of setNamespaceAware and * isNamespaceAware methods. */ @Test @@ -102,167 +91,132 @@ public class SAXParserFactTest { } /** - * Testcase to test the functionality of setNamespaceAware and getFeature() + * Test the functionality of setNamespaceAware and getFeature() * methods for namespaces property. + * @throws Exception If any errors occur. */ @Test - public void testFeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(NAMESPACES)); + public void testFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(NAMESPACES)); - spf.setNamespaceAware(true); - assertTrue(spf.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setNamespaceAware(true); + assertTrue(spf.getFeature(NAMESPACES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for namespaces property. + * @throws Exception If any errors occur. */ @Test - public void testFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); + public void testFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACES, true); - assertTrue(spf.getFeature(NAMESPACES)); + spf.setFeature(NAMESPACES, true); + assertTrue(spf.getFeature(NAMESPACES)); - spf.setFeature(NAMESPACES, false); - assertFalse(spf.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setFeature(NAMESPACES, false); + assertFalse(spf.getFeature(NAMESPACES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for namespace-prefixes property. + * @throws Exception If any errors occur. */ @Test - public void testFeature03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); + public void testFeature03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + spf.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - spf.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); } /** - * Testcase to test the functionality of getFeature method for + * Test the functionality of getFeature method for * string-interning property. + * @throws Exception If any errors occur. */ @Test - public void testFeature04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(STRING_INTERNING)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(STRING_INTERNING)); } /** - * Testcase to test the functionality of getFeature and setValidating + * Test the functionality of getFeature and setValidating * methods for validation property. + * @throws Exception If any errors occur. */ @Test - public void testFeature05() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(VALIDATION)); - spf.setValidating(true); - assertTrue(spf.getFeature(VALIDATION)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature05() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(VALIDATION)); + spf.setValidating(true); + assertTrue(spf.getFeature(VALIDATION)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for validation property. + * @throws Exception If any errors occur. */ @Test - public void testFeature06() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - - spf.setFeature(VALIDATION, true); - assertTrue(spf.getFeature(VALIDATION)); - - spf.setFeature(VALIDATION, false); - assertFalse(spf.getFeature(VALIDATION)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature06() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(VALIDATION, true); + assertTrue(spf.getFeature(VALIDATION)); + spf.setFeature(VALIDATION, false); + assertFalse(spf.getFeature(VALIDATION)); } /** - * Testcase to test the functionality of getFeature method for + * Test the functionality of getFeature method for * external-general-entities property. + * @throws Exception If any errors occur. */ @Test - public void testFeature07() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(EXTERNAL_G_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature07() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(EXTERNAL_G_ENTITIES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for external-general-entities property. + * @throws Exception If any errors occur. */ @Test - public void testFeature08() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(EXTERNAL_G_ENTITIES, false); - assertFalse(spf.getFeature(EXTERNAL_G_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature08() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(EXTERNAL_G_ENTITIES, false); + assertFalse(spf.getFeature(EXTERNAL_G_ENTITIES)); } /** - * Testcase to test the functionality of getFeature method for + * Test the functionality of getFeature method for * external-parameter-entities property. + * @throws Exception If any errors occur. */ @Test - public void testFeature09() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(EXTERNAL_P_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature09() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(EXTERNAL_P_ENTITIES)); } /** - * Testcase to test the functionality of setFeature method for + * Test the functionality of setFeature method for * external-parameter-entitie property. + * @throws Exception If any errors occur. */ @Test - public void testFeature10() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(EXTERNAL_P_ENTITIES, false); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature10() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(EXTERNAL_P_ENTITIES, false); + assertFalse(spf.getFeature(EXTERNAL_P_ENTITIES)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java index af2c5a683b7..920f0917ff7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,14 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; - import java.io.File; import java.io.FileInputStream; +import java.io.FilePermission; import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.xml.sax.HandlerBase; @@ -43,16 +41,15 @@ import org.xml.sax.helpers.DefaultHandler; /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest { - +public class SAXParserTest extends JAXPFileReadOnlyBaseTest { /** * Provide SAXParser. * - * @throws SAXException - * @throws ParserConfigurationException + * @return a data provider contains a SAXParser instance. + * @throws Exception If any errors occur. */ @DataProvider(name = "parser-provider") - public Object[][] getParser() throws ParserConfigurationException, SAXException { + public Object[][] getParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxparser = spf.newSAXParser(); return new Object[][] { { saxparser } }; @@ -62,498 +59,454 @@ public class SAXParserTest { * Test case with FileInputStream null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse01(SAXParser saxparser) throws IllegalArgumentException { + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse01(SAXParser saxparser) throws Exception { + FileInputStream instream = null; + saxparser.parse(instream, new HandlerBase()); + } + + /** + * Test with by setting URI as null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse02(SAXParser saxparser) throws Exception { + String uri = null; + saxparser.parse(uri, new HandlerBase()); + } + + /** + * Test with non-existence URI, parsing should fail and throw IOException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = { SAXException.class }, + dataProvider = "parser-provider") + public void testParse03(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); try { - FileInputStream instream = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + saxparser.parse("", new HandlerBase()); + } finally { + setPermissions(); } } /** - * Testcase with an error in xml file, parsing should fail and throw + * Test with File null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse04(SAXParser saxparser) throws Exception { + File file = null; + saxparser.parse(file, new HandlerBase()); + } + + /** + * Test with empty string as File, parsing should fail and throw * SAXException. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse02(SAXParser saxparser) throws SAXException { + public void testParse05(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - saxparser.parse(instream, handler); - } catch (IOException e) { - failUnexpected(e); + saxparser.parse(new File(""), new HandlerBase()); + } finally { + setPermissions(); } } /** - * Testcase with a valid in xml file, parser should parse the xml document. - */ - @Test(dataProvider = "parser-provider") - public void testParse03(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - } catch (IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse04(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input source, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse05(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "parsertest.xml")); - saxparser.parse(instream, handler, new File(TestUtils.XML_DIR).toURI().toASCIIString()); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with uri null, parsing should fail and throw + * Test with input source null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse07(SAXParser saxparser) throws IllegalArgumentException { - try { - String uri = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(uri, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse06(SAXParser saxparser) throws Exception { + InputSource is = null; + saxparser.parse(is, new HandlerBase()); } /** - * Testcase with non-existant uri, parsing should fail and throw - * IOException. - * - * @throws SAXException - * @throws IOException - */ - @Test(expectedExceptions = { SAXException.class, IOException.class }, dataProvider = "parser-provider") - public void testParse08(SAXParser saxparser) throws SAXException, IOException { - String uri = " "; - - HandlerBase handler = new HandlerBase(); - saxparser.parse(uri, handler); - - } - - /** - * Testcase with proper uri, parser should parse successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse09(SAXParser saxparser) { - try { - File file = new File(TestUtils.XML_DIR, "correct.xml"); - HandlerBase handler = new HandlerBase(); - saxparser.parse(file.toURI().toASCIIString(), handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with File null, parsing should fail and throw + * Test with FileInputStream null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse10(SAXParser saxparser) throws IllegalArgumentException { - try { - File file = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse07(SAXParser saxparser) throws Exception { + FileInputStream instream = null; + saxparser.parse(instream, new DefaultHandler()); } /** - * Testcase with empty string as File, parsing should fail and throw - * SAXException. - * - * @throws SAXException - */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse11(SAXParser saxparser) throws SAXException { - try { - HandlerBase handler = new HandlerBase(); - File file = new File(""); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with xml file that has errors parsing should fail and throw - * SAXException. - * - * @throws SAXException - */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse12(SAXParser saxparser) throws SAXException { - try { - HandlerBase handler = new HandlerBase(); - File file = new File(TestUtils.XML_DIR, "valid.xml"); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with xml file that has no errors Parser should successfully - * parse the xml document. - */ - @Test(dataProvider = "parser-provider") - public void testParse13(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - File file = new File(TestUtils.XML_DIR, "correct.xml"); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase with input source null, parsing should fail and throw + * Test with URI null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse14(SAXParser saxparser) throws IllegalArgumentException { - try { - InputSource is = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse08(SAXParser saxparser) throws Exception { + String uri = null; + saxparser.parse(uri, new DefaultHandler()); } /** - * Testcase with input source attached an invaild xml, parsing should fail - * and throw SAXException. - * - * @throws SAXException - */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse15(SAXParser saxparser) throws SAXException { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with input source attached an vaild xml, parser should - * successfully parse the xml document. - */ - @Test(dataProvider = "parser-provider") - public void testParse16(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with FileInputStream null, parsing should fail and throw - * IllegalArgumentException. - * - * @throws IllegalArgumentException - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse17(SAXParser saxparser) throws IllegalArgumentException { - try { - FileInputStream instream = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with an error in xml file, parsing should fail and throw - * SAXException. - * - * @throws SAXException - */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse18(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - saxparser.parse(instream, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse19(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - } catch (IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse20(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input source, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse21(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "parsertest.xml")); - saxparser.parse(instream, handler, new File(TestUtils.XML_DIR).toURI().toASCIIString()); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase with uri null, parsing should fail and throw - * IllegalArgumentException. - * - * @throws IllegalArgumentException - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse23(SAXParser saxparser) throws IllegalArgumentException { - try { - String uri = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(uri, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with non-existant uri, parsing should fail and throw + * Test with non-existence URI, parsing should fail and throw * SAXException or IOException. * - * @throws SAXException - * @throws IOException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = { SAXException.class, IOException.class }, dataProvider = "parser-provider") - public void testParse24(SAXParser saxparser) throws SAXException, IOException { + @Test(expectedExceptions = { SAXException.class, IOException.class }, + dataProvider = "parser-provider") + public void testParse09(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir + "/../-", "read")); String uri = " "; + try { + saxparser.parse(uri, new DefaultHandler()); + } finally { + setPermissions(); + } + } + + /** + * Test with empty string as File, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") + public void testParse10(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); + File file = new File(""); + try { + saxparser.parse(file, new DefaultHandler()); + } finally { + setPermissions(); + } + } + + /** + * Test with File null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse11(SAXParser saxparser) throws Exception { + saxparser.parse((File) null, new DefaultHandler()); + } + + /** + * Test with input source null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse12(SAXParser saxparser) throws Exception { + InputSource is = null; + saxparser.parse(is, new DefaultHandler()); + } + + /** + * Test with an error in XML file, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse13(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File( + XML_DIR, "invalid.xml"))) { + saxparser.parse(instream, new HandlerBase()); + } + } + + /** + * Test with a valid in XML file, parser should parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse14(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "parsertest.xml"), + new HandlerBase()); + } + + /** + * Test with valid input stream, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse15(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { + saxparser.parse(instream, new HandlerBase()); + } + } + + /** + * Test with valid input source, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse16(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "parsertest.xml"))) { + saxparser.parse(instream, new HandlerBase(), + new File(XML_DIR).toURI().toASCIIString()); + } + } + + /** + * Test with proper URI, parser should parse successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse17(SAXParser saxparser) throws Exception { + File file = new File(XML_DIR, "correct.xml"); + saxparser.parse(file.toURI().toASCIIString(), new HandlerBase()); + } + + /** + * Test with XML file that has errors parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse18(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "valid.xml"), new HandlerBase()); + } + + /** + * Test with XML file that has no errors Parser should successfully + * parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse19(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "correct.xml"), new HandlerBase()); + } + + /** + * Test with input source attached an invalid XML, parsing should fail + * and throw SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse20(SAXParser saxparser) throws Exception { + try(FileInputStream instream = new FileInputStream(new File(XML_DIR, + "invalid.xml"))) { + saxparser.parse(new InputSource(instream), new HandlerBase()); + } + } + + /** + * Test with input source attached an valid XML, parser should + * successfully parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse21(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { + saxparser.parse(new InputSource(instream), new HandlerBase()); + } + } + + /** + * Test with an error in xml file, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse22(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "invalid.xml"))) { + saxparser.parse(instream, new DefaultHandler()); + } + } + + /** + * Test with valid input stream, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse23(SAXParser saxparser) throws Exception { DefaultHandler handler = new DefaultHandler(); - saxparser.parse(uri, handler); - + saxparser.parse(new File(XML_DIR, "parsertest.xml"), handler); } /** - * Testcase with proper uri, parser should parse successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse25(SAXParser saxparser) { - try { - File file = new File(TestUtils.XML_DIR, "correct.xml"); - - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(file.toURI().toASCIIString(), handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with File null, parsing should fail and throw - * IllegalArgumentException. + * Test with valid input stream, parser should parse the XML document + * successfully. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse26(SAXParser saxparser) throws IllegalArgumentException { - try { + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse24(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { DefaultHandler handler = new DefaultHandler(); - saxparser.parse((File) null, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + saxparser.parse(instream, handler); } } /** - * Testcase with empty string as File, parsing should fail and throw + * Test with valid input source, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse25(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "parsertest.xml"))) { + saxparser.parse(instream, new DefaultHandler(), + new File(XML_DIR).toURI().toASCIIString()); + } + } + + /** + * Test with proper URI, parser should parse successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse26(SAXParser saxparser) throws Exception { + File file = new File(XML_DIR, "correct.xml"); + saxparser.parse(file.toURI().toASCIIString(), new DefaultHandler()); + } + + /** + * Test with XML file that has errors, parsing should fail and throw * SAXException. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse27(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(""); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse27(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "valid.xml"), new DefaultHandler()); } /** - * Testcase with xml file that has errors, parsing should fail and throw - * SAXException. + * Test with XML file that has no errors, parser should successfully + * parse the XML document. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse28(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(TestUtils.XML_DIR, "valid.xml"); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse28(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "correct.xml"), new DefaultHandler()); } /** - * Testcase with xml file that has no errors, parser should successfully - * parse the xml document. - */ - @Test(dataProvider = "parser-provider") - public void testParse29(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(TestUtils.XML_DIR, "correct.xml"); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with input source null, parsing should fail and throw - * IllegalArgumentException. + * Test with an invalid XML file, parser should throw SAXException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse30(SAXParser saxparser) throws IllegalArgumentException { - try { - InputSource is = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse29(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "invalid.xml"))) { + saxparser.parse(new InputSource(instream), new DefaultHandler()); } } /** - * Testcase with an invalid xml file, parser should throw SAXException. + * Test case to parse an XML file that not use namespaces. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse31(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse30(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "correct.xml"))) { + saxparser.parse(new InputSource(instream), new DefaultHandler()); } } /** - * Test case to parse an xml file that not use namespaces. + * Test case to parse an XML file that uses namespaces. + * + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse32(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Test case to parse an xml file that uses namespaces. - */ - @Test - public void testParse33() { - try { + @Test(groups = {"readLocalFiles"}) + public void testParse31() throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "ns4.xml"))) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "ns4.xml")); - saxparser.parse(instream, handler); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); + spf.newSAXParser().parse(instream, new HandlerBase()); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java index 9bfd3ef4c4e..c396d73259b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,260 +23,239 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; - -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.xml.sax.Parser; import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; -import org.xml.sax.XMLReader; import org.xml.sax.ext.DeclHandler; import org.xml.sax.ext.LexicalHandler; /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest02 { - final String DOM_NODE = "http://xml.org/sax/properties/dom-node"; - final String XML_STRING = "http://xml.org/sax/properties/xml-string"; - final String DECL_HANDLER = "http://xml.org/sax/properties/declaration-handler"; - final String LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; +public class SAXParserTest02 extends JAXPBaseTest { + private static final String DOM_NODE = "http://xml.org/sax/properties/dom-node"; + private static final String XML_STRING = "http://xml.org/sax/properties/xml-string"; + private static final String DECL_HANDLER = "http://xml.org/sax/properties/declaration-handler"; + private static final String LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; /** * Provide SAXParser. * - * @throws SAXException - * @throws ParserConfigurationException + * @return a data provider contains a SAXParser instance. + * @throws Exception If any errors occur. */ @DataProvider(name = "parser-provider") - public Object[][] getParser() throws ParserConfigurationException, SAXException { + public Object[][] getParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxparser = spf.newSAXParser(); return new Object[][] { { saxparser } }; } /** - * Testcase to test the default functionality (No validation) of the parser. + * Test to test the default functionality (No validation) of the parser. + * + * @param saxparser a SAXParser instance. */ @Test(dataProvider = "parser-provider") public void testValidate01(SAXParser saxparser) { - try { - assertFalse(saxparser.isValidating()); - } catch (FactoryConfigurationError e) { - failUnexpected(e); - } - + assertFalse(saxparser.isValidating()); } /** - * Testcase to test the functionality of setValidating and isvalidating + * Test to test the functionality of setValidating and isValidating * methods. + * + * @throws Exception If any errors occur. */ @Test - public void testValidate02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setValidating(true); - spf.newSAXParser(); - assertTrue(spf.isValidating()); - } catch (FactoryConfigurationError | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } - + public void testValidate02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setValidating(true); + spf.newSAXParser(); + assertTrue(spf.isValidating()); } /** - * Test case to test isNamespaceAware() method. By default, namespaces are + * Test isNamespaceAware() method. By default, namespaces are * not supported. + * + * @param saxparser a SAXParser instance. */ @Test(dataProvider = "parser-provider") public void testNamespace01(SAXParser saxparser) { - try { - assertFalse(saxparser.isNamespaceAware()); - } catch (FactoryConfigurationError e) { - failUnexpected(e); - } - + assertFalse(saxparser.isNamespaceAware()); } /** * Test case to test setnamespaceAware() method. + * + * @throws Exception If any errors occur. */ @Test - public void testNamespace02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - assertTrue(saxparser.isNamespaceAware()); - } catch (FactoryConfigurationError | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } - + public void testNamespace02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxparser = spf.newSAXParser(); + assertTrue(saxparser.isNamespaceAware()); } /** * Test case to test if the getParser() method returns instance of Parser. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testParser01(SAXParser saxparser) { - try { - Parser parser = saxparser.getParser(); - } catch (FactoryConfigurationError | SAXException e) { - failUnexpected(e); - } - + public void testParser01(SAXParser saxparser) throws SAXException { + assertNotNull(saxparser.getParser()); } /** * Test case to test if the getXMLReader() method returns instance of * XMLReader. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testXmlReader01(SAXParser saxparser) { - try { - XMLReader xmlReader = saxparser.getXMLReader(); - } catch (FactoryConfigurationError | SAXException e) { - failUnexpected(e); - } + public void testXmlReader01(SAXParser saxparser) throws SAXException { + assertNotNull(saxparser.getXMLReader()); } /** * Test whether the xml-string property is not supported. * - * @throws SAXNotSupportedException + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ - @Test(expectedExceptions = SAXNotSupportedException.class, dataProvider = "parser-provider") - public void testProperty01(SAXParser saxparser) throws SAXNotSupportedException { - try { - Object object = saxparser.getProperty(XML_STRING); - } catch (SAXNotRecognizedException e) { - failUnexpected(e); - } + @Test(expectedExceptions = SAXNotSupportedException.class, + dataProvider = "parser-provider") + public void testProperty01(SAXParser saxparser) throws SAXException { + saxparser.getProperty(XML_STRING); } /** * Test whether the dom-node property is not supported. * - * @throws SAXNotSupportedException + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ - @Test(expectedExceptions = SAXNotSupportedException.class, dataProvider = "parser-provider") - public void testProperty02(SAXParser saxparser) throws SAXNotSupportedException { - try { - Object object = saxparser.getProperty(DOM_NODE); - } catch (SAXNotRecognizedException e) { - failUnexpected(e); - } + @Test(expectedExceptions = SAXNotSupportedException.class, + dataProvider = "parser-provider") + public void testProperty02(SAXParser saxparser) throws SAXException { + saxparser.getProperty(DOM_NODE); } /** * Test the default lexical-handler not exists. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty03(SAXParser saxparser) { - try { - assertNull(saxparser.getProperty(LEXICAL_HANDLER)); - } catch (SAXException e) { - failUnexpected(e); - } - + public void testProperty03(SAXParser saxparser) throws SAXException { + assertNull(saxparser.getProperty(LEXICAL_HANDLER)); } /** * Test the default declaration-handler not exists. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty04(SAXParser saxparser) { - - try { - assertNull(saxparser.getProperty(DECL_HANDLER)); - } catch (SAXException e) { - failUnexpected(e); - } + public void testProperty04(SAXParser saxparser) throws SAXException { + assertNull(saxparser.getProperty(DECL_HANDLER)); } /** * Test to set and get the lexical-handler. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty05(SAXParser saxparser) { - try { - MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); - saxparser.setProperty(LEXICAL_HANDLER, myLexicalHandler); - Object object = saxparser.getProperty(LEXICAL_HANDLER); - assertTrue(object instanceof LexicalHandler); - } catch (SAXException e) { - failUnexpected(e); - } + public void testProperty05(SAXParser saxparser) throws SAXException { + MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); + saxparser.setProperty(LEXICAL_HANDLER, myLexicalHandler); + assertTrue(saxparser.getProperty(LEXICAL_HANDLER) instanceof LexicalHandler); } /** * Test to set and get the declaration-handler. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty06(SAXParser saxparser) { - try { - MyDeclHandler myDeclHandler = new MyDeclHandler(); - saxparser.setProperty(DECL_HANDLER, myDeclHandler); - Object object = saxparser.getProperty(DECL_HANDLER); - assertTrue(object instanceof DeclHandler); - } catch (SAXException e) { - failUnexpected(e); - } - + public void testProperty06(SAXParser saxparser) throws SAXException { + MyDeclHandler myDeclHandler = new MyDeclHandler(); + saxparser.setProperty(DECL_HANDLER, myDeclHandler); + assertTrue(saxparser.getProperty(DECL_HANDLER) instanceof DeclHandler); } /** - * Customized LexicalHandler used for test. + * Customized LexicalHandler used for test. An empty implementation for + * LexicalHandler. */ private class MyLexicalHandler implements LexicalHandler { + @Override public void comment(char[] ch, int start, int length) { } + @Override public void endCDATA() { } + @Override public void endDTD() { } + @Override public void endEntity(String name) { } + @Override public void startCDATA() { } + @Override public void startDTD(String name, String publicId, String systemId) { } + @Override public void startEntity(String name) { } } /** - * Customized DeclHandler used for test. + * Customized DeclHandler used for test. An empty implementation for + * DeclHandler. */ private class MyDeclHandler implements DeclHandler { + @Override public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) { } + @Override public void elementDecl(String name, String model) { } + @Override public void externalEntityDecl(String name, String publicId, String systemId) { } + @Override public void internalEntityDecl(String name, String value) { } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java index efe12c595d6..636b1e29a90 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,17 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - import java.io.File; -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; +import java.io.FilePermission; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.fail; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.xml.sax.SAXException; @@ -41,68 +41,70 @@ import org.xml.sax.SAXException; /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest03 { +public class SAXParserTest03 extends JAXPFileReadOnlyBaseTest { /** * Provide SAXParserFactory. * - * @throws Exception + * @return a dimensional contains. */ @DataProvider(name = "input-provider") public Object[][] getFactory() { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); - MyErrorHandler handler = MyErrorHandler.newInstance(); - return new Object[][] { { spf, handler } }; + return new Object[][] { { spf, MyErrorHandler.newInstance() } }; } /** * parsertest.xml holds a valid document. This method tests the validating * parser. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate01(SAXParserFactory spf, MyErrorHandler handler) { - try { - SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - assertFalse(handler.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate01(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { + spf.newSAXParser().parse(new File(XML_DIR, "parsertest.xml"), handler); + assertFalse(handler.isErrorOccured()); } /** * validns.xml holds a valid document with XML namespaces in it. This method * tests the Validating parser with namespace processing on. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate02(SAXParserFactory spf, MyErrorHandler handler) { - try { + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate02(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "validns.xml"), handler); - assertFalse(handler.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + spf.newSAXParser().parse(new File(XML_DIR, "validns.xml"), handler); + assertFalse(handler.isErrorOccured()); } /** * invalidns.xml holds an invalid document with XML namespaces in it. This * method tests the validating parser with namespace processing on. It * should throw validation error. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate03(SAXParserFactory spf, MyErrorHandler handler) { + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate03(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { try { spf.setNamespaceAware(true); SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "invalidns.xml"), handler); - failUnexpected(new RuntimeException()); - } catch (ParserConfigurationException | SAXException | IOException e) { - if (e instanceof SAXException) { - assertTrue(handler.errorOccured); - } + saxparser.parse(new File(XML_DIR, "invalidns.xml"), handler); + fail("Expecting SAXException here"); + } catch (SAXException e) { + assertTrue(handler.isErrorOccured()); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest01.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java similarity index 63% rename from jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest01.java rename to jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java index 504ee8626c4..42069ea2785 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest01.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,21 +26,16 @@ package javax.xml.transform.ptests; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.w3c.dom.Attr; @@ -48,7 +43,6 @@ import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -56,48 +50,36 @@ import org.xml.sax.helpers.XMLReaderFactory; * DOM parse on test file to be compared with golden output file. No Exception * is expected. */ -public class DOMResultTest01 { +public class DOMResultTest extends JAXPFileBaseTest { /** * Unit test for simple DOM parsing. + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String resultFile = CLASS_DIR + "domresult01.out"; + public void testcase01() throws Exception { + String resultFile = USER_DIR + "domresult01.out"; String goldFile = GOLDEN_DIR + "domresult01GF.out"; String xsltFile = XML_DIR + "cities.xsl"; String xmlFile = XML_DIR + "cities.xml"; - try { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory) TransformerFactory.newInstance(); - SAXSource saxSource = new SAXSource(new InputSource(xsltFile)); - TransformerHandler handler - = saxTFactory.newTransformerHandler(saxSource); + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory) TransformerFactory.newInstance(); + SAXSource saxSource = new SAXSource(new InputSource(xsltFile)); + TransformerHandler handler + = saxTFactory.newTransformerHandler(saxSource); - DOMResult result = new DOMResult(); + DOMResult result = new DOMResult(); - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(xmlFile); - Node node = result.getNode(); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(resultFile))) { - writeNodes(node, writer); - } - assertTrue(compareWithGold(goldFile, resultFile)); - } catch (SAXException | TransformerConfigurationException - | IllegalArgumentException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if(Files.exists(resultPath)) - Files.delete(resultPath); - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Node node = result.getNode(); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(resultFile))) { + writeNodes(node, writer); } + assertTrue(compareWithGold(goldFile, resultFile)); } /** diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java index 9867ab44c56..19417830ac6 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,14 @@ package javax.xml.transform.ptests; import java.io.File; +import java.io.FilePermission; import javax.xml.transform.ErrorListener; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import org.testng.annotations.Test; @@ -37,7 +39,7 @@ import org.testng.annotations.Test; /** * Class containing the test cases for ErrorListener interface */ -public class ErrorListenerTest implements ErrorListener { +public class ErrorListenerTest extends JAXPBaseTest implements ErrorListener { /** * Define ErrorListener's status. */ @@ -58,9 +60,10 @@ public class ErrorListenerTest implements ErrorListener { try { TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setErrorListener (listener); + setPermissions(new FilePermission(XML_DIR + "invalid.xsl", "read")); tfactory.newTransformer(new StreamSource( new File(XML_DIR + "invalid.xsl"))); - fail("We expect an Exception here"); + fail("Expect TransformerConfigurationException here"); } catch (TransformerConfigurationException ex) { assertEquals(listener.status, ListenerStatus.FATAL); } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest01.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest.java similarity index 65% rename from jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest01.java rename to jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest.java index abb558f32f9..ca4c67ed21b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest01.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,80 +25,73 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Unit test for SAXSource sourceToInputSource API. */ -public class SAXSourceTest01 { +public class SAXSourceTest extends JAXPFileReadOnlyBaseTest { /** - * Test file name + * Test style-sheet file name */ private final String TEST_FILE = XML_DIR + "cities.xsl"; /** * Test obtaining a SAX InputSource object from a Source object. + * + * @throws IOException reading file error. */ - @Test - public void source2inputsource01() { - try { - StreamSource streamSource = new StreamSource ( - new FileInputStream (TEST_FILE)); + @Test(groups = {"readLocalFiles"}) + public void source2inputsource01() throws IOException { + try (FileInputStream fis = new FileInputStream(TEST_FILE)) { + StreamSource streamSource = new StreamSource(fis); assertNotNull(SAXSource.sourceToInputSource(streamSource)); - } catch (FileNotFoundException ex) { - failUnexpected(ex); } } /** * This test case tries to get InputSource from DOMSource using * sourceToInputSource method. It is not possible and hence null is - * expected. This is a negative test case + * expected. This is a negative test case, + * + * @throws Exception If any errors occur. */ - @Test - public void source2inputsource02() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.newDocumentBuilder().parse(new File(TEST_FILE)); - assertNull(SAXSource.sourceToInputSource(new DOMSource(null))); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } - + @Test(groups = {"readLocalFiles"}) + public void source2inputsource02() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.newDocumentBuilder().parse(new File(TEST_FILE)); + assertNull(SAXSource.sourceToInputSource(new DOMSource(null))); } /** * This test case tries to get InputSource from SAXSource using * sourceToInputSource method. This will also check if the systemId * remained the same. This is a positive test case. + * + * @throws IOException reading file error. */ - @Test - public void source2inputsource03() { + @Test(groups = {"readLocalFiles"}) + public void source2inputsource03() throws IOException { String SYSTEM_ID = "file:///" + XML_DIR; - try { + try (FileInputStream fis = new FileInputStream(TEST_FILE)) { SAXSource saxSource = - new SAXSource(new InputSource(new FileInputStream(TEST_FILE))); + new SAXSource(new InputSource(fis)); saxSource.setSystemId(SYSTEM_ID); assertEquals(SAXSource.sourceToInputSource(saxSource).getSystemId(), SYSTEM_ID); - } catch (FileNotFoundException ex) { - failUnexpected(ex); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest.java new file mode 100644 index 00000000000..60da93acc73 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest.java @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.xml.transform.ptests; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; +import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TemplatesHandler; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * Test newTransformerhandler() method which takes StreamSource as argument can + * be set to XMLReader. + */ +public class SAXTFactoryTest extends JAXPFileBaseTest { + /** + * Test style-sheet file. + */ + private static final String XSLT_FILE = XML_DIR + "cities.xsl"; + + /** + * Test style-sheet file. + */ + private static final String XSLT_INCL_FILE = XML_DIR + "citiesinclude.xsl"; + + /** + * Test XML file. + */ + private static final String XML_FILE = XML_DIR + "cities.xml"; + + /** + * SAXTFactory.newTransformerhandler() method which takes SAXSource as + * argument can be set to XMLReader. SAXSource has input XML file as its + * input source. XMLReader has a transformer handler which write out the + * result to output file. Test verifies output file is same as golden file. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase01() throws Exception { + String outputFile = USER_DIR + "saxtf001.out"; + String goldFile = GOLDEN_DIR + "saxtf001GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory) TransformerFactory.newInstance(); + TransformerHandler handler = saxTFactory.newTransformerHandler(new StreamSource(XSLT_FILE)); + Result result = new StreamResult(fos); + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * SAXTFactory.newTransformerhandler() method which takes SAXSource as + * argument can be set to XMLReader. SAXSource has input XML file as its + * input source. XMLReader has a content handler which write out the result + * to output file. Test verifies output file is same as golden file. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase02() throws Exception { + String outputFile = USER_DIR + "saxtf002.out"; + String goldFile = GOLDEN_DIR + "saxtf002GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile); + FileInputStream fis = new FileInputStream(XSLT_FILE)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory) TransformerFactory.newInstance(); + SAXSource ss = new SAXSource(); + ss.setInputSource(new InputSource(fis)); + + TransformerHandler handler = saxTFactory.newTransformerHandler(ss); + Result result = new StreamResult(fos); + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test for newTransformerhandler(Source). DcoumentBuilderFactory is + * namespace awareness, DocumentBuilder parse xslt file as DOMSource. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase03() throws Exception { + String outputFile = USER_DIR + "saxtf003.out"; + String goldFile = GOLDEN_DIR + "saxtf003GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new File(XSLT_FILE)); + Node node = (Node)document; + DOMSource domSource= new DOMSource(node); + + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + TransformerHandler handler = + saxTFactory.newTransformerHandler(domSource); + Result result = new StreamResult(fos); + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Negative test for newTransformerHandler when relative URI is in XML file. + * + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = TransformerConfigurationException.class) + public void transformerHandlerTest04() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new File(XSLT_INCL_FILE)); + DOMSource domSource= new DOMSource(document); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + saxTFactory.newTransformerHandler(domSource); + } + + /** + * Unit test for XMLReader parsing when relative URI is used in xsl file and + * SystemId was set. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase05() throws Exception { + String outputFile = USER_DIR + "saxtf005.out"; + String goldFile = GOLDEN_DIR + "saxtf005GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new File(XSLT_INCL_FILE)); + Node node = (Node)document; + DOMSource domSource= new DOMSource(node); + + domSource.setSystemId("file:///" + XML_DIR); + + TransformerHandler handler = + saxTFactory.newTransformerHandler(domSource); + Result result = new StreamResult(fos); + + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test newTransformerHandler with a DOMSource. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase06() throws Exception { + String outputFile = USER_DIR + "saxtf006.out"; + String goldFile = GOLDEN_DIR + "saxtf006GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Node node = (Node)docBuilder.parse(new File(XSLT_INCL_FILE)); + + DOMSource domSource = new DOMSource(node, "file:///" + XML_DIR); + TransformerHandler handler = + saxTFactory.newTransformerHandler(domSource); + + Result result = new StreamResult(fos); + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Test newTransformerHandler with a Template Handler. + * + * @throws Exception If any errors occur. + */ + public void testcase08() throws Exception { + String outputFile = USER_DIR + "saxtf008.out"; + String goldFile = GOLDEN_DIR + "saxtf008GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + + TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); + reader.setContentHandler(thandler); + reader.parse(XSLT_FILE); + TransformerHandler tfhandler + = saxTFactory.newTransformerHandler(thandler.getTemplates()); + + Result result = new StreamResult(fos); + tfhandler.setResult(result); + + reader.setContentHandler(tfhandler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Test newTransformerHandler with a Template Handler along with a relative + * URI in the style-sheet file. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase09() throws Exception { + String outputFile = USER_DIR + "saxtf009.out"; + String goldFile = GOLDEN_DIR + "saxtf009GF.out"; + + try (FileOutputStream fos = new FileOutputStream(outputFile)) { + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + + TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); + thandler.setSystemId("file:///" + XML_DIR); + reader.setContentHandler(thandler); + reader.parse(XSLT_INCL_FILE); + TransformerHandler tfhandler= + saxTFactory.newTransformerHandler(thandler.getTemplates()); + Result result = new StreamResult(fos); + tfhandler.setResult(result); + reader.setContentHandler(tfhandler); + reader.parse(XML_FILE); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test for contentHandler setter/getter along reader as handler's + * parent. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase10() throws Exception { + String outputFile = USER_DIR + "saxtf010.out"; + String goldFile = GOLDEN_DIR + "saxtf010GF.out"; + // The transformer will use a SAX parser as it's reader. + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + XMLFilter filter = + saxTFactory.newXMLFilter(new StreamSource(XSLT_FILE)); + filter.setParent(reader); + filter.setContentHandler(new MyContentHandler(outputFile)); + + // Now, when you call transformer.parse, it will set itself as + // the content handler for the parser object (it's "parent"), and + // will then call the parse method on the parser. + filter.parse(new InputSource(XML_FILE)); + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test for contentHandler setter/getter with parent. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase11() throws Exception { + String outputFile = USER_DIR + "saxtf011.out"; + String goldFile = GOLDEN_DIR + "saxtf011GF.out"; + // The transformer will use a SAX parser as it's reader. + XMLReader reader = XMLReaderFactory.createXMLReader(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new File(XSLT_FILE)); + Node node = (Node)document; + DOMSource domSource= new DOMSource(node); + + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory)TransformerFactory.newInstance(); + XMLFilter filter = saxTFactory.newXMLFilter(domSource); + + filter.setParent(reader); + filter.setContentHandler(new MyContentHandler(outputFile)); + + // Now, when you call transformer.parse, it will set itself as + // the content handler for the parser object (it's "parent"), and + // will then call the parse method on the parser. + filter.parse(new InputSource(XML_FILE)); + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test for contentHandler setter/getter. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase12() throws Exception { + String outputFile = USER_DIR + "saxtf012.out"; + String goldFile = GOLDEN_DIR + "saxtf012GF.out"; + // The transformer will use a SAX parser as it's reader. + XMLReader reader = XMLReaderFactory.createXMLReader(); + + InputSource is = new InputSource(new FileInputStream(XSLT_FILE)); + SAXSource saxSource = new SAXSource(); + saxSource.setInputSource(is); + + SAXTransformerFactory saxTFactory = (SAXTransformerFactory)TransformerFactory.newInstance(); + XMLFilter filter = saxTFactory.newXMLFilter(saxSource); + + filter.setParent(reader); + filter.setContentHandler(new MyContentHandler(outputFile)); + + // Now, when you call transformer.parse, it will set itself as + // the content handler for the parser object (it's "parent"), and + // will then call the parse method on the parser. + filter.parse(new InputSource(XML_FILE)); + assertTrue(compareWithGold(goldFile, outputFile)); + } + + /** + * Unit test for TemplatesHandler setter/getter. + * + * @throws Exception If any errors occur. + */ + @Test + public void testcase13() throws Exception { + String outputFile = USER_DIR + "saxtf013.out"; + String goldFile = GOLDEN_DIR + "saxtf013GF.out"; + try(FileInputStream fis = new FileInputStream(XML_FILE)) { + // The transformer will use a SAX parser as it's reader. + XMLReader reader = XMLReaderFactory.createXMLReader(); + + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory) TransformerFactory.newInstance(); + TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); + // I have put this as it was complaining about systemid + thandler.setSystemId("file:///" + USER_DIR); + + reader.setContentHandler(thandler); + reader.parse(XSLT_FILE); + XMLFilter filter + = saxTFactory.newXMLFilter(thandler.getTemplates()); + filter.setParent(reader); + + filter.setContentHandler(new MyContentHandler(outputFile)); + filter.parse(new InputSource(fis)); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest001.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest001.java deleted file mode 100644 index 112b1996fbf..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest001.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.xml.transform.ptests; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerhandler() method which takes StreamSource as argument can - * be set to XMLReader. - */ -public class SAXTFactoryTest001 { - /** - * SAXTFactory.newTransformerhandler() method which takes SAXSource as - * argument can be set to XMLReader. SAXSource has input XML file as its - * input source. XMLReader has a transformer handler which write out the - * result to output file. Test verifies output file is same as golden file. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf001.out"; - String goldFile = GOLDEN_DIR + "saxtf001GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory) TransformerFactory.newInstance(); - TransformerHandler handler = saxTFactory.newTransformerHandler( - new StreamSource(xsltFile)); - Result result = new StreamResult(fos); - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | TransformerConfigurationException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest002.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest002.java deleted file mode 100644 index 775edb7d0b9..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest002.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerhandler() method which takes SAXSource as argument can - * be set to XMLReader. - */ -public class SAXTFactoryTest002 { - /** - * SAXTFactory.newTransformerhandler() method which takes SAXSource as - * argument can be set to XMLReader. SAXSource has input XML file as its - * input source. XMLReader has a content handler which write out the result - * to output file. Test verifies output file is same as golden file. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf002.out"; - String goldFile = GOLDEN_DIR + "saxtf002GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile); - FileInputStream fis = new FileInputStream(xsltFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory) TransformerFactory.newInstance(); - SAXSource ss = new SAXSource(); - ss.setInputSource(new InputSource(fis)); - - TransformerHandler handler = saxTFactory.newTransformerHandler(ss); - Result result = new StreamResult(fos); - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest003.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest003.java deleted file mode 100644 index b7bc37bd403..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest003.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerhandler() method which takes DOMSource as argument can - * be set to XMLReader. - */ -public class SAXTFactoryTest003 { - /** - * Unit test for newTransformerhandler(Source). DcoumentBuilderFactory is - * namespace awareness, DocumentBuilder parse xslt file as DOMSource. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf003.out"; - String goldFile = GOLDEN_DIR + "saxtf003GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new File(xsltFile)); - Node node = (Node)document; - DOMSource domSource= new DOMSource(node); - - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - TransformerHandler handler = - saxTFactory.newTransformerHandler(domSource); - Result result = new StreamResult(fos); - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (TransformerConfigurationException | ParserConfigurationException - | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest004.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest004.java deleted file mode 100644 index 419cae137d8..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest004.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.IOException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -/* - * TransformerConfigurationException expected when there is relative URI is used - * in citiesinclude.xsl file - */ -public class SAXTFactoryTest004 { - /** - * Negative test for newTransformerHandler when relative URI is in XML file. - * @throws TransformerConfigurationException If for some reason the - * TransformerHandler can not be created. - */ - @Test(expectedExceptions = TransformerConfigurationException.class) - public void transformerHandlerTest01() throws TransformerConfigurationException { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new File(XML_DIR + "citiesinclude.xsl")); - DOMSource domSource= new DOMSource(document); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - saxTFactory.newTransformerHandler(domSource); - } catch (ParserConfigurationException | IOException | SAXException ex) { - failUnexpected(ex); - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest005.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest005.java deleted file mode 100644 index 51691500543..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest005.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test SAXSource API when relative URI is used in xsl file and SystemId was set - */ -public class SAXTFactoryTest005 { - /** - * Unit test for XMLReader parsing when relative URI is used in xsl file and - * SystemId was set. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf005.out"; - String goldFile = GOLDEN_DIR + "saxtf005GF.out"; - String xsltFile = XML_DIR + "citiesinclude.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new File(xsltFile)); - Node node = (Node)document; - DOMSource domSource= new DOMSource(node); - - domSource.setSystemId("file:///" + XML_DIR); - - TransformerHandler handler = - saxTFactory.newTransformerHandler(domSource); - Result result = new StreamResult(fos); - - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (TransformerConfigurationException | ParserConfigurationException - | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest006.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest006.java deleted file mode 100644 index 9dd330cb125..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest006.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerHandler with a DOMSource and StreamResult set. - */ -public class SAXTFactoryTest006 extends TransformerTestConst{ - /** - * Unit test newTransformerHandler with a DOMSource. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf006.out"; - String goldFile = GOLDEN_DIR + "saxtf006GF.out"; - String xsltFile = XML_DIR + "citiesinclude.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Node node = (Node)docBuilder.parse(new File(xsltFile)); - - DOMSource domSource = new DOMSource(node, "file:///" + XML_DIR); - TransformerHandler handler = - saxTFactory.newTransformerHandler(domSource); - - Result result = new StreamResult(fos); - handler.setResult(result); - reader.setContentHandler(handler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (TransformerConfigurationException | ParserConfigurationException - | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest008.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest008.java deleted file mode 100644 index d4353c0bc0d..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest008.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TemplatesHandler; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerHandler with a Template Handler. - */ -public class SAXTFactoryTest008 { - /** - * Test newTransformerHandler with a Template Handler. - */ - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf008.out"; - String goldFile = GOLDEN_DIR + "saxtf008GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - - TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); - reader.setContentHandler(thandler); - reader.parse(xsltFile); - TransformerHandler tfhandler - = saxTFactory.newTransformerHandler(thandler.getTemplates()); - - Result result = new StreamResult(fos); - tfhandler.setResult(result); - - reader.setContentHandler(tfhandler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } - -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest009.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest009.java deleted file mode 100644 index 4930928a3aa..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest009.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.Result; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TemplatesHandler; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test newTransformerHandler with a Template Handler along with a relative URI - * in the xslt file. - */ -public class SAXTFactoryTest009 { - /** - * Test newTransformerHandler with a Template Handler along with a relative - * URI in the xslt file. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf009.out"; - String goldFile = GOLDEN_DIR + "saxtf009GF.out"; - String xsltFile = XML_DIR + "citiesinclude.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - XMLReader reader = XMLReaderFactory.createXMLReader(); - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - - TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); - thandler.setSystemId("file:///" + XML_DIR); - reader.setContentHandler(thandler); - reader.parse(xsltFile); - TransformerHandler tfhandler= - saxTFactory.newTransformerHandler(thandler.getTemplates()); - Result result = new StreamResult(fos); - tfhandler.setResult(result); - reader.setContentHandler(tfhandler); - reader.parse(xmlFile); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest010.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest010.java deleted file mode 100644 index e2aaa39ec0f..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest010.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test XMLFilter parse InputSource along with customized ContentHandler. - */ -public class SAXTFactoryTest010 { - /** - * Unit test for contentHandler setter/getter along reader as handler's - * parent. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf010.out"; - String goldFile = GOLDEN_DIR + "saxtf010GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try { - // The transformer will use a SAX parser as it's reader. - XMLReader reader = XMLReaderFactory.createXMLReader(); - - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - XMLFilter filter = - saxTFactory.newXMLFilter(new StreamSource(xsltFile)); - - filter.setParent(reader); - filter.setContentHandler(new MyContentHandler(outputFile)); - - // Now, when you call transformer.parse, it will set itself as - // the content handler for the parser object (it's "parent"), and - // will then call the parse method on the parser. - filter.parse(new InputSource(xmlFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest011.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest011.java deleted file mode 100644 index 8676995f703..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest011.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test XMLFilter parse InputSource along with customized ContentHandler by - * using SAX parser as it's reader. - */ -public class SAXTFactoryTest011 { - /** - * Unit test for contentHandler setter/getter with parent. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf011.out"; - String goldFile = GOLDEN_DIR + "saxtf011GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try { - // The transformer will use a SAX parser as it's reader. - XMLReader reader = XMLReaderFactory.createXMLReader(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new File(xsltFile)); - Node node = (Node)document; - DOMSource domSource= new DOMSource(node); - - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory)TransformerFactory.newInstance(); - XMLFilter filter = saxTFactory.newXMLFilter(domSource); - - filter.setParent(reader); - filter.setContentHandler(new MyContentHandler(outputFile)); - - // Now, when you call transformer.parse, it will set itself as - // the content handler for the parser object (it's "parent"), and - // will then call the parse method on the parser. - filter.parse(new InputSource(xmlFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException - | ParserConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest012.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest012.java deleted file mode 100644 index 42ca180cd99..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest012.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test XMLFilter parse InputSource along with customized ContentHandler by - * using SAX parser as it's reader. - */ -public class SAXTFactoryTest012 { - /** - * Unit test for contentHandler setter/getter. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf012.out"; - String goldFile = GOLDEN_DIR + "saxtf012GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - try { - // The transformer will use a SAX parser as it's reader. - XMLReader reader = XMLReaderFactory.createXMLReader(); - - InputSource is = new InputSource(new FileInputStream(xsltFile)); - SAXSource saxSource = new SAXSource(); - saxSource.setInputSource(is); - - SAXTransformerFactory saxTFactory = (SAXTransformerFactory)TransformerFactory.newInstance(); - XMLFilter filter = saxTFactory.newXMLFilter(saxSource); - - filter.setParent(reader); - filter.setContentHandler(new MyContentHandler(outputFile)); - - // Now, when you call transformer.parse, it will set itself as - // the content handler for the parser object (it's "parent"), and - // will then call the parse method on the parser. - filter.parse(new InputSource(xmlFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest013.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest013.java deleted file mode 100644 index 9c4bddd8801..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest013.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TemplatesHandler; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * Test XMLFilter parse InputSource along with TemplatesHandler. - */ -public class SAXTFactoryTest013 { - /** - * Unit test for TemplatesHandler setter/getter. - */ - @Test - public void testcase01() { - String outputFile = CLASS_DIR + "saxtf013.out"; - String goldFile = GOLDEN_DIR + "saxtf013GF.out"; - String xsltFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - try { - // The transformer will use a SAX parser as it's reader. - XMLReader reader = XMLReaderFactory.createXMLReader(); - - SAXTransformerFactory saxTFactory - = (SAXTransformerFactory) TransformerFactory.newInstance(); - TemplatesHandler thandler = saxTFactory.newTemplatesHandler(); - // I have put this as it was complaining about systemid - thandler.setSystemId("file:///" + CLASS_DIR); - - reader.setContentHandler(thandler); - reader.parse(xsltFile); - XMLFilter filter - = saxTFactory.newXMLFilter(thandler.getTemplates()); - filter.setParent(reader); - - filter.setContentHandler( - new MyContentHandler(outputFile)); - filter.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (SAXException | IOException | TransformerConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest.java similarity index 92% rename from jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java rename to jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest.java index f5166978203..9ff71b900ae 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,10 +34,11 @@ import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.failUnexpected; import org.testng.annotations.Test; import org.w3c.dom.Document; @@ -47,7 +48,7 @@ import org.xml.sax.SAXException; * Test a StreamResult using a file name that contains URL characters that need * to be encoded. */ -public class StreamResultTest01 { +public class StreamResultTest extends JAXPFileBaseTest { /** * Unit test for StreamResult. */ @@ -82,7 +83,7 @@ public class StreamResultTest01 { DOMSource domSource = new DOMSource(document); StreamSource streamSource = new StreamSource(new FileInputStream(xmlFile)); - File streamResultFile = new File(CLASS_DIR + file); + File streamResultFile = new File(USER_DIR + file); StreamResult streamResult = new StreamResult(streamResultFile); Transformer transformer = TransformerFactory.newInstance().newTransformer(domSource); diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java index 74219b25f01..02384973de7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,11 +24,8 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; @@ -36,21 +33,20 @@ import javax.xml.transform.dom.DOMSource; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for SAXParserFactory API */ -public class TfClearParamTest { +public class TfClearParamTest extends JAXPFileReadOnlyBaseTest { /** - * Test xslt file. + * Test style-sheet file name. */ private final String XSL_FILE = XML_DIR + "cities.xsl"; @@ -72,193 +68,164 @@ public class TfClearParamTest { /** * Obtains transformer's parameter with the same name that set before. Value * should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear01() { - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME).toString(), PARAM_VALUE); - } catch (TransformerConfigurationException ex) { - failUnexpected(ex); - } - + public void clear01() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME).toString(), PARAM_VALUE); } /** * Obtains transformer's parameter with the a name that wasn't set before. * Null is expected. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear02() { - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter whose initiated with a stream source with - * the a name that set before. Value should be same as set one. - */ - @Test - public void clear03() { - try { - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(new StreamSource(new File(XSL_FILE))); - - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter whose initiated with a stream source with - * the a name that wasn't set before. Null is expected. - */ - @Test - public void clear04() { - try { - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(new StreamSource(new File(XSL_FILE))); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } - - } - - /** - * Obtains transformer's parameter whose initiated with a sax source with - * the a name that set before. Value should be same as set one. - */ - @Test - public void clear05() { - try { - InputSource is = new InputSource(new FileInputStream(XSL_FILE)); - SAXSource saxSource = new SAXSource(); - saxSource.setInputSource(is); - - Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); - - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter whose initiated with a sax source with - * the a name that wasn't set before. Null is expected. - */ - @Test - public void clear06() { - try { - InputSource is = new InputSource(new FileInputStream(XSL_FILE)); - SAXSource saxSource = new SAXSource(); - saxSource.setInputSource(is); - - Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); - - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter whose initiated with a dom source with - * the a name that set before. Value should be same as set one. - */ - @Test - public void clear07() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_FILE)); - DOMSource domSource = new DOMSource((Node)document); - - Transformer transformer = tfactory.newTransformer(domSource); - - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter whose initiated with a dom source with - * the a name that wasn't set before. Null is expected. - */ - @Test - public void clear08() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_FILE)); - DOMSource domSource = new DOMSource((Node)document); - - Transformer transformer = tfactory.newTransformer(domSource); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + public void clear02() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); } /** * Obtains transformer's parameter with a short name that set before. Value * should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear09() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); + public void clear03() throws TransformerConfigurationException { + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); - transformer.setParameter(SHORT_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(SHORT_PARAM_NAME).toString(), PARAM_VALUE); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + transformer.setParameter(SHORT_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(SHORT_PARAM_NAME).toString(), PARAM_VALUE); } /** * Obtains transformer's parameter with a short name that set with an integer * object before. Value should be same as the set integer object. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear10() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); + public void clear04() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); - int intObject = 5; - transformer.setParameter(SHORT_PARAM_NAME, intObject); - assertEquals(transformer.getParameter(SHORT_PARAM_NAME), intObject); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); + int intObject = 5; + transformer.setParameter(SHORT_PARAM_NAME, intObject); + assertEquals(transformer.getParameter(SHORT_PARAM_NAME), intObject); + } + + /** + * Obtains transformer's parameter whose initiated with a stream source with + * the a name that set before. Value should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + @Test (groups = {"readLocalFiles"}) + public void clear05() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(new StreamSource(new File(XSL_FILE))); + + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); + } + + /** + * Obtains transformer's parameter whose initiated with a stream source with + * the a name that wasn't set before. Null is expected. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + @Test (groups = {"readLocalFiles"}) + public void clear06() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(new StreamSource(new File(XSL_FILE))); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); + } + + /** + * Obtains transformer's parameter whose initiated with a sax source with + * the a name that set before. Value should be same as set one. + * @throws Exception If any errors occur. + */ + @Test (groups = {"readLocalFiles"}) + public void clear07() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_FILE)) { + SAXSource saxSource = new SAXSource(); + saxSource.setInputSource(new InputSource(fis)); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); } } + + /** + * Obtains transformer's parameter whose initiated with a sax source with + * the a name that wasn't set before. Null is expected. + * @throws Exception If any errors occur. + */ + @Test (groups = {"readLocalFiles"}) + public void clear08() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_FILE)) { + SAXSource saxSource = new SAXSource(); + saxSource.setInputSource(new InputSource(fis)); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); + } + } + + /** + * Obtains transformer's parameter whose initiated with a dom source with + * the a name that set before. Value should be same as set one. + * @throws Exception If any errors occur. + */ + @Test (groups = {"readLocalFiles"}) + public void clear09() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_FILE)); + DOMSource domSource = new DOMSource((Node)document); + + Transformer transformer = tfactory.newTransformer(domSource); + + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); + } + + /** + * Obtains transformer's parameter whose initiated with a dom source with + * the a name that wasn't set before. Null is expected. + * @throws Exception If any errors occur. + */ + @Test (groups = {"readLocalFiles"}) + public void clear10() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_FILE)); + DOMSource domSource = new DOMSource((Node)document); + + Transformer transformer = tfactory.newTransformer(domSource); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); + } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java index 866c1c0597d..1a936cbaa4b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,14 @@ package javax.xml.transform.ptests; import java.io.File; +import java.io.FilePermission; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -38,13 +40,14 @@ import org.testng.annotations.Test; /** * Basic test for TransformerException specification. */ -public class TransformerExcpTest { +public class TransformerExcpTest extends JAXPBaseTest { /** - * Transform an unformatted xslt file. TransformerException is thrown. + * Transform an unformatted style-sheet file. TransformerException is thrown. */ @Test public void tfexception() { try { + setPermissions(new FilePermission(XML_DIR + "-", "read")); // invalid.xsl has well-formedness error. Therefore transform throws // TransformerException StreamSource streamSource @@ -60,6 +63,8 @@ public class TransformerExcpTest { assertNotNull(e.getException()); assertNull(e.getLocationAsString()); assertEquals(e.getMessageAndLocation(),e.getMessage()); + } finally { + setPermissions(); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java index 45099ebb19c..04c255aceb9 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,39 +24,35 @@ package javax.xml.transform.ptests; import java.io.*; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.*; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.w3c.dom.*; -import org.xml.sax.SAXException; /** * Class containing the test cases for TransformerFactory API's * getAssociatedStyleSheet method. */ -public class TransformerFactoryTest { +public class TransformerFactoryTest extends JAXPFileBaseTest { /** * This test case checks for the getAssociatedStylesheet method * of TransformerFactory. * The style sheet returned is then copied to an tfactory01.out - * It will then be verified to see if it matches the golden files + * It will then be verified to see if it matches the golden files. + * + * @throws Exception If any errors occur. */ @Test - public void tfactory01() { - String outputFile = CLASS_DIR + "tfactory01.out"; + public void tfactory01() throws Exception { + String outputFile = USER_DIR + "tfactory01.out"; String goldFile = GOLDEN_DIR + "tfactory01GF.out"; String xmlFile = XML_DIR + "TransformerFactoryTest.xml"; String xmlURI = "file:///" + XML_DIR; @@ -76,10 +72,7 @@ public class TransformerFactoryTest { "Modern", null); Transformer t = tFactory.newTransformer(); t.transform(s, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException - | TransformerException | SAXException ex) { - failUnexpected(ex); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java index f138c7d157a..8e718b082d3 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,9 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import java.util.Properties; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.ErrorListener; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; @@ -39,150 +36,132 @@ import javax.xml.transform.dom.DOMSource; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Basic test cases for Transformer API */ -public class TransformerTest { +public class TransformerTest extends JAXPFileReadOnlyBaseTest { /** * XSLT file serves every test method. */ private final static String TEST_XSL = XML_DIR + "cities.xsl"; /** - * This tests if newTransformer(StreamSource) method returns Transformer + * This tests if newTransformer(StreamSource) method returns Transformer. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ - @Test - public void transformer01() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - StreamSource streamSource = new StreamSource( - new File(TEST_XSL)); - Transformer transformer = tfactory.newTransformer(streamSource); - assertNotNull(transformer); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + @Test (groups = {"readLocalFiles"}) + public void transformer01() throws TransformerConfigurationException { + TransformerFactory tfactory = TransformerFactory.newInstance(); + StreamSource streamSource = new StreamSource( + new File(TEST_XSL)); + Transformer transformer = tfactory.newTransformer(streamSource); + assertNotNull(transformer); } /** - * This tests if newTransformer(SAXSource) method returns Transformer + * This tests if newTransformer(SAXSource) method returns Transformer. + * @throws Exception If any errors occur. */ - @Test - public void transformer02() { - try { + @Test (groups = {"readLocalFiles"}) + public void transformer02() throws Exception { + try (FileInputStream fis = new FileInputStream(TEST_XSL)) { TransformerFactory tfactory = TransformerFactory.newInstance(); - InputSource is = new InputSource( - new FileInputStream(TEST_XSL)); - SAXSource saxSource = new SAXSource(is); + SAXSource saxSource = new SAXSource(new InputSource(fis)); Transformer transformer = tfactory.newTransformer(saxSource); assertNotNull(transformer); - } catch (TransformerConfigurationException | FileNotFoundException ex){ - failUnexpected(ex); } } /** - * This tests if newTransformer(DOMSource) method returns Transformer + * This tests if newTransformer(DOMSource) method returns Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer03() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); + @Test (groups = {"readLocalFiles"}) + public void transformer03() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = tfactory.newTransformer(domSource); - assertNotNull(transformer); - } catch (TransformerConfigurationException | IOException - | ParserConfigurationException | SAXException ex){ - failUnexpected(ex); - } + Transformer transformer = tfactory.newTransformer(domSource); + assertNotNull(transformer); } /** - * This tests set/get ErrorListener methods of Transformer + * This tests set/get ErrorListener methods of Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer04() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + @Test (groups = {"readLocalFiles"}) + public void transformer04() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = TransformerFactory.newInstance() - .newTransformer(domSource); - transformer.setErrorListener(new MyErrorListener()); - assertNotNull(transformer.getErrorListener()); - assertTrue(transformer.getErrorListener() instanceof MyErrorListener); - } catch (IOException | IllegalArgumentException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(domSource); + transformer.setErrorListener(new MyErrorListener()); + assertNotNull(transformer.getErrorListener()); + assertTrue(transformer.getErrorListener() instanceof MyErrorListener); } /** - * This tests getOutputProperties() method of Transformer + * This tests getOutputProperties() method of Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer05() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + @Test (groups = {"readLocalFiles"}) + public void transformer05() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(domSource); - Properties prop = transformer.getOutputProperties(); + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(domSource); + Properties prop = transformer.getOutputProperties(); - assertEquals(prop.getProperty("indent"), "yes"); - assertEquals(prop.getProperty("method"), "xml"); - assertEquals(prop.getProperty("encoding"), "UTF-8"); - assertEquals(prop.getProperty("standalone"), "no"); - assertEquals(prop.getProperty("version"), "1.0"); - assertEquals(prop.getProperty("omit-xml-declaration"), "no"); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException ex){ - failUnexpected(ex); - } + assertEquals(prop.getProperty("indent"), "yes"); + assertEquals(prop.getProperty("method"), "xml"); + assertEquals(prop.getProperty("encoding"), "UTF-8"); + assertEquals(prop.getProperty("standalone"), "no"); + assertEquals(prop.getProperty("version"), "1.0"); + assertEquals(prop.getProperty("omit-xml-declaration"), "no"); } /** - * This tests getOutputProperty() method of Transformer + * This tests getOutputProperty() method of Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer06() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); + @Test (groups = {"readLocalFiles"}) + public void transformer06() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = tfactory.newTransformer(domSource); - assertEquals(transformer.getOutputProperty("method"), "xml"); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException | IllegalArgumentException ex){ - failUnexpected(ex); - } + Transformer transformer = tfactory.newTransformer(domSource); + assertEquals(transformer.getOutputProperty("method"), "xml"); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java index 9f6a2bef82f..0f50b349eec 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,42 +25,34 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * Here a transformer is created using DOMSource. Some specific output property * is set on transformer. Then transform(StreamSource, StreamResult) is tested. */ -public class TransformerTest02 { +public class TransformerTest02 extends JAXPFileBaseTest { /** * Unit test for transform(StreamSource, StreamResult). + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "transformer02.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "transformer02.out"; String goldFile = GOLDEN_DIR + "transformer02GF.out"; String xsltFile = XML_DIR + "cities.xsl"; String xmlFile = XML_DIR + "cities.xml"; @@ -69,9 +61,8 @@ public class TransformerTest02 { FileOutputStream fos = new FileOutputStream(outputFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(xsltFile)); - DOMSource domSource = new DOMSource(document); + DOMSource domSource = new DOMSource(dbf.newDocumentBuilder(). + parse(new File(xsltFile))); Transformer transformer = TransformerFactory.newInstance(). newTransformer(domSource); @@ -79,20 +70,8 @@ public class TransformerTest02 { StreamResult streamResult = new StreamResult(fos); transformer.setOutputProperty("indent", "no"); - transformer.transform( streamSource, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | IllegalArgumentException - | ParserConfigurationException | TransformerException - | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + transformer.transform(streamSource, streamResult); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java index 2035d16b0c7..23855e52cb2 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,30 +25,20 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Properties; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * Here Properties Object is populated with required properties.A transformer @@ -56,13 +46,15 @@ import org.xml.sax.SAXException; * for transformer. Then transform(StreamSource, StreamResult) is used for * transformation. This tests the setOutputProperties() method. */ -public class TransformerTest03 { +public class TransformerTest03 extends JAXPFileBaseTest { /** * Test for Transformer.setOutputProperties method. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "transformer03.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "transformer03.out"; String goldFile = GOLDEN_DIR + "transformer03GF.out"; String xsltFile = XML_DIR + "cities.xsl"; String xmlFile = XML_DIR + "cities.xml"; @@ -81,29 +73,14 @@ public class TransformerTest03 { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(xsltFile)); - DOMSource domSource = new DOMSource(document); + DOMSource domSource = new DOMSource(dbf.newDocumentBuilder(). + parse(new File(xsltFile))); Transformer transformer = TransformerFactory.newInstance(). newTransformer(domSource); - StreamSource streamSource = new StreamSource(fis); - StreamResult streamResult = new StreamResult(fos); - transformer.setOutputProperties(properties); - transformer.transform( streamSource, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException - | IOException | TransformerException ex){ - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + transformer.transform(new StreamSource(fis), new StreamResult(fos)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java index d5ddfaeb9be..05889f6715c 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,15 +24,10 @@ package javax.xml.transform.ptests; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMSource; @@ -40,18 +35,17 @@ import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileBaseTest; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * URIResolver should be invoked when transform happens. */ -public class URIResolverTest implements URIResolver { +public class URIResolverTest extends JAXPFileBaseTest implements URIResolver { /** * System ID constant. */ @@ -72,9 +66,8 @@ public class URIResolverTest implements URIResolver { */ private final static String XSL_TEMP_FILE = "temp/cities.xsl"; - /** - * expected Href. + * expected HREF. */ private final String validateHref; @@ -83,6 +76,14 @@ public class URIResolverTest implements URIResolver { */ private final String validateBase; + /** + * Default constructor for testng invocation. + */ + public URIResolverTest(){ + validateHref = null; + validateBase = null; + } + /** * Constructor for setting expected Href and expected Base URI. * @param validateHref expected Href @@ -110,166 +111,144 @@ public class URIResolverTest implements URIResolver { /** * This is to test the URIResolver.resolve() method when a transformer is - * created using StreamSource. xsl file has xsl:include in it + * created using StreamSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver01() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver01() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_INCLUDE_FILE)) { TransformerFactory tfactory = TransformerFactory.newInstance(); URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); tfactory.setURIResolver(resolver); - StreamSource streamSource = new StreamSource(new FileInputStream(XSL_INCLUDE_FILE)); + StreamSource streamSource = new StreamSource(fis); streamSource.setSystemId(SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(streamSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(streamSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using DOMSource. xsl file has xsl:include in it + * created using DOMSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver02() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); - tfactory.setURIResolver(resolver); + @Test (groups = {"readLocalFiles"}) + public static void resolver02() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); + URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); + tfactory.setURIResolver(resolver); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(XSL_INCLUDE_FILE); - DOMSource domSource = new DOMSource(document, SYSTEM_ID); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(XSL_INCLUDE_FILE); + DOMSource domSource = new DOMSource(document, SYSTEM_ID); - Transformer transformer = tfactory.newTransformer(domSource); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + assertNotNull(tfactory.newTransformer(domSource)); } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using SAXSource. xsl file has xsl:include in it + * created using SAXSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver03() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver03() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_INCLUDE_FILE)){ URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - InputSource is = new InputSource(new FileInputStream(XSL_INCLUDE_FILE)); + InputSource is = new InputSource(fis); is.setSystemId(SYSTEM_ID); SAXSource saxSource = new SAXSource(is); - - Transformer transformer = tfactory.newTransformer(saxSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(saxSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using StreamSource. xsl file has xsl:import in it + * created using StreamSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver04() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver04() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_IMPORT_FILE)) { URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - - StreamSource streamSource = new StreamSource(new FileInputStream(XSL_IMPORT_FILE)); + StreamSource streamSource = new StreamSource(fis); streamSource.setSystemId(SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(streamSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(streamSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using DOMSource. xsl file has xsl:import in it + * created using DOMSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver05() { - try { - URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); - TransformerFactory tfactory = TransformerFactory.newInstance(); - tfactory.setURIResolver(resolver); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_IMPORT_FILE)); - DOMSource domSource = new DOMSource(document, SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(domSource); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException ex){ - failUnexpected(ex); - } - + @Test (groups = {"readLocalFiles"}) + public static void resolver05() throws Exception { + URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); + TransformerFactory tfactory = TransformerFactory.newInstance(); + tfactory.setURIResolver(resolver); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_IMPORT_FILE)); + DOMSource domSource = new DOMSource(document, SYSTEM_ID); + assertNotNull(tfactory.newTransformer(domSource)); } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using SAXSource. xsl file has xsl:import in it + * created using SAXSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver06() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver06() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_IMPORT_FILE)){ URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - - InputSource is = new InputSource(new FileInputStream(XSL_IMPORT_FILE)); + InputSource is = new InputSource(fis); is.setSystemId(SYSTEM_ID); SAXSource saxSource = new SAXSource(is); - - Transformer transformer = tfactory.newTransformer(saxSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(saxSource)); } - } /** * This is to test the URIResolver.resolve() method when there is an error * in the file. + * + * @throws Exception If any errors occur. */ - @Test - public static void docResolver01() { - try { + @Test (groups = {"readLocalFiles"}) + public static void docResolver01() throws Exception { + try (FileInputStream fis = new FileInputStream(XML_DIR + "doctest.xsl")) { URIResolverTest resolver = new URIResolverTest("temp/colors.xml", SYSTEM_ID); - TransformerFactory tfactory = TransformerFactory.newInstance(); - - StreamSource streamSource = new StreamSource( - new FileInputStream(XML_DIR + FILE_SEP + "doctest.xsl")); + StreamSource streamSource = new StreamSource(fis); streamSource.setSystemId(SYSTEM_ID); - System.err.println(streamSource.getSystemId()); - Transformer transformer = tfactory.newTransformer(streamSource); + Transformer transformer = TransformerFactory.newInstance().newTransformer(streamSource); transformer.setURIResolver(resolver); - File f = new File(XML_DIR + FILE_SEP + "myFake.xml"); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(f); + File f = new File(XML_DIR + "myFake.xml"); + Document document = DocumentBuilderFactory.newInstance(). + newDocumentBuilder().parse(f); // Use a Transformer for output DOMSource source = new DOMSource(document); - System.err.println("Ignore the following output -- just dumping it here"); StreamResult result = new StreamResult(System.err); + // No exception is expected because resolver resolve wrong URI. transformer.transform(source, result); - } catch (IOException | ParserConfigurationException | SAXException - | TransformerException ex) { - failUnexpected(ex); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java index ee2420eb7e7..489fe838d32 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,22 @@ package javax.xml.transform.ptests.othervm; import javax.xml.transform.*; +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.fail; import org.testng.annotations.Test; /** * Negative test for set invalid TransformerFactory property. */ -public class TFCErrorTest{ +public class TFCErrorTest extends JAXPBaseTest { @Test(expectedExceptions = ClassNotFoundException.class) public void tfce01() throws Exception { try{ - System.setProperty("javax.xml.transform.TransformerFactory","xx"); - TransformerFactory tFactory = TransformerFactory.newInstance(); - } catch (TransformerFactoryConfigurationError error) { - throw error.getException(); + setSystemProperty("javax.xml.transform.TransformerFactory","xx"); + TransformerFactory.newInstance(); + fail("Expect TransformerFactoryConfigurationError here"); + } catch (TransformerFactoryConfigurationError expected) { + throw expected.getException(); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java index bbd4a58678d..bf9c2502ee9 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package javax.xml.xpath.ptests; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -31,7 +31,6 @@ import java.nio.file.Paths; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import static javax.xml.xpath.XPathConstants.BOOLEAN; import static javax.xml.xpath.XPathConstants.NODE; @@ -41,7 +40,7 @@ import static javax.xml.xpath.XPathConstants.STRING; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import static javax.xml.xpath.ptests.XPathTestConst.XML_DIR; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -49,12 +48,11 @@ import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for XPathExpression API. */ -public class XPathExpressionTest { +public class XPathExpressionTest extends JAXPFileReadOnlyBaseTest { /** * Document object for testing XML file. */ @@ -87,13 +85,11 @@ public class XPathExpressionTest { /** * Create Document object and XPath object for every time - * @throws ParserConfigurationException If the factory class cannot be - * loaded, instantiated - * @throws SAXException If any parse errors occur. - * @throws IOException If operation on xml file failed. + * @throws Exception If any errors occur. */ @BeforeTest - public void setup() throws ParserConfigurationException, SAXException, IOException { + public void setup() throws Exception { + setPermissions(new FilePermission(XML_PATH.toFile().toString(), "read")); document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(XML_PATH.toFile()); xpath = XPathFactory.newInstance().newXPath(); } @@ -101,230 +97,200 @@ public class XPathExpressionTest { /** * Test for evaluate(java.lang.Object item,QName returnType)throws * XPathExpressionException. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression01() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). - evaluate(document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression01() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). + evaluate(document, STRING), "6"); } /** * evaluate(java.lang.Object item,QName returnType) throws NPE if input * source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression02() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression02() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); } /** * evaluate(java.lang.Object item,QName returnType) throws NPE if returnType * is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression03() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(document, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression03() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(document, null); } /** * Test for method evaluate(java.lang.Object item,QName returnType).If a * request is made to evaluate the expression in the absence of a context * item, simple expressions, such as "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression04() { - try { - assertEquals(xpath.compile("1+1").evaluate(document, STRING), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression04() throws XPathExpressionException { + assertEquals(xpath.compile("1+1").evaluate(document, STRING), "2"); } /** * evaluate(java.lang.Object item,QName returnType) throws IAE If returnType * is not one of the types defined in XPathConstants. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPathExpression05() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(document, TEST_QNAME); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression05() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(document, TEST_QNAME); } /** * evaluate(java.lang.Object item,QName returnType) return correct boolean * value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression06() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). + public void testCheckXPathExpression06() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(document, BOOLEAN), true); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } } /** * evaluate(java.lang.Object item,QName returnType) return correct boolean * value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression07() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_B). - evaluate(document, BOOLEAN), false); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression07() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_B). + evaluate(document, BOOLEAN), false); } /** * evaluate(java.lang.Object item,QName returnType) return correct number * value when return type is Double. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression08() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NUMBER), 6d); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression08() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NUMBER), 6d); } /** * evaluate(java.lang.Object item,QName returnType) evaluate an attribute * value which returnType is Node. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression09() { - try { - Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NODE); - assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression09() throws XPathExpressionException { + Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NODE); + assertEquals(attr.getValue(), "6"); } /** * evaluate(java.lang.Object item,QName returnType) evaluate an attribute * value which returnType is NodeList. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression10() { - try { - NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NODESET); - Attr attr = (Attr) nodeList.item(0); - assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression10() throws XPathExpressionException { + NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NODESET); + Attr attr = (Attr) nodeList.item(0); + assertEquals(attr.getValue(), "6"); } /** * Test for evaluate(java.lang.Object item) when returnType is left off of * the XPath.evaluate method, all expressions are evaluated to a String * value. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression11() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression11() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document), "6"); } /** * evaluate(java.lang.Object item) throws NPE if expression is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression12() { - try { - xpath.compile(null).evaluate(document); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression12() throws XPathExpressionException { + xpath.compile(null).evaluate(document); } /** * evaluate(java.lang.Object item) when a request is made to evaluate the * expression in the absence of a context item, simple expressions, such as * "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression13() { - try { - assertEquals(xpath.compile("1+1").evaluate(document), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression13() throws XPathExpressionException { + assertEquals(xpath.compile("1+1").evaluate(document), "2"); } /** * evaluate(java.lang.Object item) throws NPE if document is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression14() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression14() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null); } /** * valuate(InputSource source) return a string value if return type is * String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression15() { + @Test (groups = {"readLocalFiles"}) + public void testCheckXPathExpression15() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is)), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source) throws NPE if input source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression16() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression16() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null); } /** - * evaluate(InputSource source) throws NPE if expression is null + * evaluate(InputSource source) throws NPE if expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression17() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression17() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(null).evaluate(new InputSource(is)); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -332,14 +298,12 @@ public class XPathExpressionTest { * evaluate(InputSource source) throws XPathExpressionException if * returnType is String junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression18() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression18() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile("-*&").evaluate(new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -347,67 +311,63 @@ public class XPathExpressionTest { * evaluate(InputSource source) throws XPathExpressionException if * expression is a blank string " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression19() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression19() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(" ").evaluate(new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) returns a string * value if returnType is String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression20() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression20() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), STRING), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) throws NPE if source is * null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression21() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression21() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); } /** * evaluate(InputSource source,QName returnType) throws NPE if expression is * null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression22() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression22() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(null).evaluate(new InputSource(is), STRING); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) throws NPE if returnType is * null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression23() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression23() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), null); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -415,14 +375,12 @@ public class XPathExpressionTest { * evaluate(InputSource source,QName returnType) throws * XPathExpressionException if expression is junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression24() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression24() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile("-*&").evaluate(new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -430,14 +388,12 @@ public class XPathExpressionTest { * evaluate(InputSource source,QName returnType) throws * XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression25() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression25() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(" ").evaluate(new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -445,85 +401,85 @@ public class XPathExpressionTest { * evaluate(InputSource source,QName returnType) throws * IllegalArgumentException if returnType is not one of the types defined * in XPathConstants. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPathExpression26() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = IllegalArgumentException.class) + public void testCheckXPathExpression26() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), TEST_QNAME); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct boolean * value if returnType is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression27() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression27() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), BOOLEAN), true); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct boolean * value if returnType is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression28() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression28() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_B). evaluate(new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct number * value if returnType is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression29() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression29() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) returns a node if * returnType is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression30() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression30() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NODE); assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) return a node list * if returnType is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression31() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression31() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java index d8e84c7f4a2..cc33e0a05cf 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,14 +26,14 @@ package javax.xml.xpath.ptests; import static javax.xml.xpath.XPathConstants.DOM_OBJECT_MODEL; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactoryConfigurationException; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.AssertJUnit.assertNotNull; import org.testng.annotations.Test; /** * Class containing the test cases for XPathFactory API. */ -public class XPathFactoryTest { +public class XPathFactoryTest extends JAXPBaseTest { /** * Valid URL for creating a XPath factory. */ @@ -54,21 +54,21 @@ public class XPathFactoryTest { /** * XPathFactory.newInstance(String uri) throws NPE if uri is null. + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = NullPointerException.class) - private void testCheckXPathFactory02() { - try { - XPathFactory.newInstance(null); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory02() throws XPathFactoryConfigurationException { + XPathFactory.newInstance(null); } /** * XPathFactory.newInstance(String uri) throws XPFCE if uri is just a blank * string. * - * @throws XPathFactoryConfigurationException + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = XPathFactoryConfigurationException.class) public void testCheckXPathFactory03() throws XPathFactoryConfigurationException { @@ -78,21 +78,21 @@ public class XPathFactoryTest { /** * Test for constructor - XPathFactory.newInstance(String uri) with valid * url - "http://java.sun.com/jaxp/xpath/dom". + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory04() { - try { - assertNotNull(XPathFactory.newInstance(VALID_URL)); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory04() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(VALID_URL)); } /** * Test for constructor - XPathFactory.newInstance(String uri) with invalid * url - "http://java.sun.com/jaxp/xpath/dom1". * - * @throws XPathFactoryConfigurationException + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = XPathFactoryConfigurationException.class) public void testCheckXPathFactory05() throws XPathFactoryConfigurationException { @@ -112,26 +112,24 @@ public class XPathFactoryTest { * Test for constructor - XPathFactory.newInstance(String uri) with valid * url - "http://java.sun.com/jaxp/xpath/dom" and creating XPath with * newXPath(). + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory07() { - try { - assertNotNull(XPathFactory.newInstance(VALID_URL).newXPath()); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory07() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(VALID_URL).newXPath()); } /** * Test for constructor - XPathFactory.newInstance(String uri) with valid * uri - DOM_OBJECT_MODEL.toString(). + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory08() { - try { - assertNotNull(XPathFactory.newInstance(DOM_OBJECT_MODEL)); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory08() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(DOM_OBJECT_MODEL)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java index 80f75b75eb0..cf1046508b5 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ package javax.xml.xpath.ptests; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -34,7 +34,7 @@ import org.testng.annotations.Test; /** * Class containing the test cases for XPathFunctionResolver. */ -public class XPathFunctionResolverTest { +public class XPathFunctionResolverTest extends JAXPBaseTest { /** * A XPath for evaluation environment and expressions. */ @@ -54,26 +54,22 @@ public class XPathFunctionResolverTest { /** * Test for resolveFunction(QName functionName,int arity). evaluate will * continue as long as functionName is meaningful. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathFunctionResolver01() { - try { - assertEquals(xpath.evaluate("round(1.7)", (Object)null), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathFunctionResolver01() throws XPathExpressionException { + assertEquals(xpath.evaluate("round(1.7)", (Object)null), "2"); } /** * Test for resolveFunction(QName functionName,int arity); evaluate throws * NPE if functionName is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathFunctionResolver02() { - try { - assertEquals(xpath.evaluate(null, "5"), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathFunctionResolver02() throws XPathExpressionException { + assertEquals(xpath.evaluate(null, "5"), "2"); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java index 83688101435..765cf18bae1 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package javax.xml.xpath.ptests; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -33,7 +33,6 @@ import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import static javax.xml.xpath.XPathConstants.BOOLEAN; import static javax.xml.xpath.XPathConstants.NODE; @@ -43,7 +42,7 @@ import static javax.xml.xpath.XPathConstants.STRING; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import static javax.xml.xpath.ptests.XPathTestConst.XML_DIR; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; @@ -53,12 +52,11 @@ import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for XPath API. */ -public class XPathTest { +public class XPathTest extends JAXPFileReadOnlyBaseTest { /** * Document object for testing XML file. */ @@ -91,13 +89,11 @@ public class XPathTest { /** * Create Document object and XPath object for every time - * @throws ParserConfigurationException If the factory class cannot be - * loaded, instantiated - * @throws SAXException If any parse errors occur. - * @throws IOException If operation on xml file failed. + * @throws Exception If any errors occur. */ @BeforeTest - public void setup() throws ParserConfigurationException, SAXException, IOException { + public void setup() throws Exception { + setPermissions(new FilePermission(XML_DIR + "-", "read")); document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(XML_PATH.toFile()); xpath = XPathFactory.newInstance().newXPath(); } @@ -105,62 +101,54 @@ public class XPathTest { /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType) which return type is String. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath01() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath01() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, STRING), "6"); } /** * Test for XPath.compile(java.lang.String expression) and then * evaluate(java.lang.Object item, QName returnType). + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath02() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath02() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document, STRING), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item) when the third argument is left off of the XPath.evaluate method, * all expressions are evaluated to a String value. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath03() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath03() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document), "6"); } /** * Test for XPath.compile(java.lang.String expression). If expression is * null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath04() { - try { - xpath.compile(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath04() throws XPathExpressionException { + xpath.compile(null); } /** * Test for XPath.compile(java.lang.String expression). If expression cannot * be compiled junk characters, should throw XPathExpressionException. * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath05() throws XPathExpressionException { @@ -171,7 +159,7 @@ public class XPathTest { * Test for XPath.compile(java.lang.String expression). If expression is * blank, should throw XPathExpressionException * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath06() throws XPathExpressionException { @@ -181,55 +169,46 @@ public class XPathTest { /** * Test for XPath.compile(java.lang.String expression). The expression * cannot be evaluated as this does not exist. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath07() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_B).evaluate(document, STRING), ""); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } - + public void testCheckXPath07() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_B).evaluate(document, STRING), ""); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object - * item, QName returnType). If String expression is null, should throw NPE + * item, QName returnType). If String expression is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath08() { - try { - xpath.evaluate(null, document, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath08() throws XPathExpressionException { + xpath.evaluate(null, document, STRING); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If item is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath09() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath09() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null, STRING); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If returnType is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath10() { - try { - xpath.evaluate(EXPRESSION_NAME_A, document, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath10() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, document, null); } /** @@ -237,23 +216,20 @@ public class XPathTest { * item, QName returnType). If a request is made to evaluate the expression * in the absence of a context item, simple expressions, such as "1+1", can * be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath11() { - try { - assertEquals(xpath.evaluate("1+1", document, STRING), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath11() throws XPathExpressionException { + assertEquals(xpath.evaluate("1+1", document, STRING), "2"); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) throws XPathExpressionException if expression is a empty * string "". - * . * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath12() throws XPathExpressionException { @@ -264,161 +240,141 @@ public class XPathTest { * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) throws IllegalArgumentException if returnType is not one of * the types defined in XPathConstants. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPath13() { - try { - xpath.evaluate(EXPRESSION_NAME_A, document, TEST_QNAME); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath13() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, document, TEST_QNAME); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct boolean value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath14() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, BOOLEAN), true); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath14() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, BOOLEAN), true); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns false as expression is not successful in evaluating * to any result if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath15() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_B, document, BOOLEAN), false); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath15() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_B, document, BOOLEAN), false); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct number value if return type is Number. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath16() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, NUMBER), 6d); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath16() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, NUMBER), 6d); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct string value if return type is Node. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath17() { - try { - assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, document, NODE)).getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath17() throws XPathExpressionException { + assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, document, NODE)).getValue(), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If return type is NodeList,the evaluated value * equals to "6" as expected. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath18() { - try { - NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, document, NODESET); - assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath18() throws XPathExpressionException { + NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, document, NODESET); + assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item). If expression is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath19() { - try { - xpath.evaluate(null, document); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath19() throws XPathExpressionException { + xpath.evaluate(null, document); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item). If a request is made to evaluate the expression in the absence of * a context item, simple expressions, such as "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath20() { - try { - assertEquals(xpath.evaluate("1+1", document), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath20() throws XPathExpressionException { + assertEquals(xpath.evaluate("1+1", document), "2"); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item) throws * NPE if InputSource is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath21() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath21() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null); } /** * XPath.evaluate(java.lang.String expression, InputSource source) return * correct value by looking for Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath22() { + @Test (groups = {"readLocalFiles"}) + public void testCheckXPath22() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is)), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source) throws * NPE if InputSource is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath23() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath23() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null); } /** * XPath.evaluate(java.lang.String expression, InputSource source) throws * NPE if String expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath24() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath24() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(null, new InputSource(is)); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -427,14 +383,12 @@ public class XPathTest { * If expression is junk characters, expression cannot be evaluated, should * throw XPathExpressionException. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath25() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath25() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate("-*&", new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -442,66 +396,62 @@ public class XPathTest { * XPath.evaluate(java.lang.String expression, InputSource source) throws * XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath26() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath26() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(" ", new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) returns correct string value which return type is String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath27() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath27() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), STRING), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws NPE if source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath28() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath28() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null, STRING); } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws NPE if expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath29() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath29() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(null, new InputSource(is), STRING); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, - * QName returnType) throws NPE if returnType is null . + * QName returnType) throws NPE if returnType is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath30() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath30() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), null); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -509,14 +459,12 @@ public class XPathTest { * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws XPathExpressionException if expression is junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath31() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath31() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate("-*&", new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -524,14 +472,12 @@ public class XPathTest { * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath32() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath32() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(" ", new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -539,84 +485,84 @@ public class XPathTest { * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) throws IllegalArgumentException if returnType is not * one of the types defined in XPathConstants. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPath33() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = IllegalArgumentException.class) + public void testCheckXPath33() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), TEST_QNAME); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct boolean value if return type is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath34() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath34() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), BOOLEAN), true); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct boolean value if return type is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath35() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath35() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_B, new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct number value if return type is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath36() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath36() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct string value if return type is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath37() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath37() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODE)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) which return type is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath38() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath38() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -624,57 +570,57 @@ public class XPathTest { * Test for XPath.evaluate(java.lang.String expression, InputSource iSource, * QName returnType). If return type is Boolean, should return false as * expression is not successful in evaluating to any result. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath52() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath52() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_B, new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns correct number value which return type is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath53() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath53() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns a node value if returnType is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath54() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath54() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODE)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns a node list if returnType is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath55() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath55() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java index d6491704db3..708b53376df 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ package org.xml.sax.ptests; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; @@ -30,7 +31,7 @@ import org.xml.sax.helpers.AttributesImpl; /** * Class containing the test cases for AttributesImpl API. */ -public class AttrImplTest { +public class AttrImplTest extends JAXPBaseTest { private static final String CAR_URI = "http://www.cars.com/xml"; private static final String CAR_LOCALNAME = "part"; diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java index 1b8d8a56c23..8309fc1b569 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,13 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -45,39 +38,29 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * ContentHandler has Attributes as one of its arguments. Attributes * pertaining to an element are taken into this argument and various methods * of Attributes interfaces are tested. This program uses Namespace processing - * with namespaces in xml file. This program does not use Validation + * with namespaces in XML file. This program does not use Validation */ -public class AttributesNSTest { +public class AttributesNSTest extends JAXPFileBaseTest { /** * Test for Attribute Interface's setter/getter. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "AttributesNS.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "AttributesNS.out"; String goldFile = GOLDEN_DIR + "AttributesNSGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - // http://www.saxproject.com/?selected=namespaces namespace-prefixes - //set to false to supress xmlns attributes - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - false); - SAXParser saxParser = spf.newSAXParser(); - MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); - saxParser.parse(new File(xmlFile), myAttrCHandler); - myAttrCHandler.flushAndClose(); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + // http://www.saxproject.com/?selected=namespaces namespace-prefixes + //set to false to supress xmlns attributes + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + false); + SAXParser saxParser = spf.newSAXParser(); + MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); + saxParser.parse(new File(xmlFile), myAttrCHandler); + myAttrCHandler.flushAndClose(); + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java index 3d310202401..351ceee914f 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,13 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -48,37 +41,28 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * This program uses Namespace processing without any namepsaces in xml file. * This program uses Validation */ -public class AttributesTest { +public class AttributesTest extends JAXPFileBaseTest { /** * Unit test for Attributes interface. Prints all attributes into output * file. Check it with golden file. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "Attributes.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "Attributes.out"; String goldFile = GOLDEN_DIR + "AttributesGF.out"; String xmlFile = XML_DIR + "family.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - true); - spf.setValidating(true); - SAXParser saxParser = spf.newSAXParser(); - MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); - saxParser.parse(new File(xmlFile), myAttrCHandler); - myAttrCHandler.flushAndClose(); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + spf.setValidating(true); + SAXParser saxParser = spf.newSAXParser(); + MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); + saxParser.parse(new File(xmlFile), myAttrCHandler); + myAttrCHandler.flushAndClose(); + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java index 729cef54aee..7ab081ee2b7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,24 +26,18 @@ import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -52,43 +46,34 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * transverses XML and print all visited node when XMLreader parses XML. Test * verifies output is same as the golden file. */ -public class ContentHandlerTest { +public class ContentHandlerTest extends JAXPFileBaseTest { /** * Content event handler visit all nodes to print to output file. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "Content.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "Content.out"; String goldFile = GOLDEN_DIR + "ContentGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try(FileInputStream instream = new FileInputStream(xmlFile)) { + try(FileInputStream instream = new FileInputStream(xmlFile); + MyContentHandler cHandler = new MyContentHandler(outputFile)) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - ContentHandler cHandler = new MyContentHandler(outputFile); xmlReader.setContentHandler(cHandler); - InputSource is = new InputSource(instream); - xmlReader.parse(is); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch( IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + xmlReader.parse(new InputSource(instream)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } /** * A content write out handler. */ -class MyContentHandler extends XMLFilterImpl { +class MyContentHandler extends XMLFilterImpl implements AutoCloseable { /** * Prefix to every exception. */ @@ -258,4 +243,14 @@ class MyContentHandler extends XMLFilterImpl { throw new SAXException(WRITE_ERROR, ex); } } + + /** + * Close the writer if it's initiated. + * @throws IOException if any IO error when close buffered writer. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java index cc3eecb2d9b..309c95d27e3 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,15 +26,11 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.Attributes; @@ -42,7 +38,6 @@ import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,46 +45,32 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * XMLReader parse XML with default handler that transverses XML and * print all visited node. Test verifies output is same as the golden file. */ -public class DefaultHandlerTest { +public class DefaultHandlerTest extends JAXPFileBaseTest { /** * Test default handler that transverses XML and print all visited node. + * + * @throws Exception If any errors occur. */ @Test - public void testDefaultHandler() { - String outputFile = CLASS_DIR + "DefaultHandler.out"; + public void testDefaultHandler() throws Exception { + String outputFile = USER_DIR + "DefaultHandler.out"; String goldFile = GOLDEN_DIR + "DefaultHandlerGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxparser = spf.newSAXParser(); + + MyDefaultHandler handler = new MyDefaultHandler(outputFile); + File file = new File(xmlFile); + String Absolutepath = file.getAbsolutePath(); + String newAbsolutePath = Absolutepath; + if (File.separatorChar == '\\') + newAbsolutePath = Absolutepath.replace('\\', '/'); + saxparser.parse("file:///" + newAbsolutePath, handler); + + assertTrue(compareWithGold(goldFile, outputFile)); - MyDefaultHandler handler = new MyDefaultHandler(outputFile); - File file = new File(xmlFile); - String Absolutepath = file.getAbsolutePath(); - String newAbsolutePath = Absolutepath; - if (File.separatorChar == '\\') - newAbsolutePath = Absolutepath.replace('\\', '/'); - String uri = "file:///" + newAbsolutePath; - saxparser.parse(uri, handler); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java index 5cd660bbc1a..d8ad68cd5e8 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,23 +26,19 @@ import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import org.testng.annotations.Test; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,14 +46,16 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * ErrorHandler unit test. Set a ErrorHandle to XMLReader. Capture fatal error * events in ErrorHandler. */ -public class EHFatalTest { +public class EHFatalTest extends JAXPFileBaseTest { /** * Error Handler to capture all error events to output file. Verifies the * output file is same as golden file. + * + * @throws Exception If any errors occur. */ @Test - public void testEHFatal() { - String outputFile = CLASS_DIR + "EHFatal.out"; + public void testEHFatal() throws Exception { + String outputFile = USER_DIR + "EHFatal.out"; String goldFile = GOLDEN_DIR + "EHFatalGF.out"; String xmlFile = XML_DIR + "invalid.xml"; @@ -68,25 +66,12 @@ public class EHFatalTest { xmlReader.setErrorHandler(eHandler); InputSource is = new InputSource(instream); xmlReader.parse(is); - } catch (IOException | ParserConfigurationException ex) { - failUnexpected(ex); - } catch (SAXException ex) { - System.out.println("This is expected:" + ex); + fail("Parse should throw SAXException"); + } catch (SAXException expected) { + // This is expected. } // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java index 965e535b9e2..a8731a484da 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ package org.xml.sax.ptests; import java.util.Enumeration; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; @@ -31,7 +32,7 @@ import org.xml.sax.helpers.NamespaceSupport; /** * Unit test cases for NamespaceSupport API */ -public class NSSupportTest { +public class NSSupportTest extends JAXPBaseTest { /** * Empty prefix name. */ diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java new file mode 100644 index 00000000000..72a8cf37c59 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.xml.sax.ptests; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.xml.sax.XMLReader; + +/** + * Class containing the test cases for Namespace Table defined at + * http://www.megginson.com/SAX/Java/namespaces.html + */ +public class NSTableTest extends JAXPBaseTest { + private static final String NAMESPACES = + "http://xml.org/sax/features/namespaces"; + private static final String NAMESPACE_PREFIXES = + "http://xml.org/sax/features/namespace-prefixes"; + + /** + * Here namespace processing and namespace-prefixes are enabled. + * The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxParser = spf.newSAXParser(); + + XMLReader xmlReader = saxParser.getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); + + assertTrue(xmlReader.getFeature(NAMESPACES)); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is enabled. This will make namespace-prefixes + * disabled. The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACES)); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled. This will make namespace-prefixes + * enabled. The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable03() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACES)); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled, and namespace-prefixes is + * disabled. This will make namespace processing on.The testcase tests + * XMLReader for this. This behavior only apply to crimson, not + * XERCES. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable04() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing and namespace-prefixes are enabled. + * The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature(NAMESPACE_PREFIXES,true); + assertTrue(spf.getFeature(NAMESPACES)); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is enabled. This will make namespace-prefixes + * disabled. The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + assertTrue(spf.getFeature(NAMESPACES)); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled. This will make namespace-prefixes + * enabled. The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(NAMESPACES)); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + } + /** + * Here namespace processing is disabled, and namespace-prefixes is + * disabled. This will make namespace processing on.The testcase tests + * SAXParserFactory for this. This behavior only apply to crimson, + * not xerces. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java deleted file mode 100644 index 1dc28418e0a..00000000000 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.xml.sax.ptests; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; -import org.xml.sax.XMLReader; - -/** - * Class containing the test cases for Namespace Table defined at - * http://www.megginson.com/SAX/Java/namespaces.html - */ -public class NSTableTest01 { - private static final String NAMESPACES = - "http://xml.org/sax/features/namespaces"; - private static final String NAMESPACE_PREFIXES = - "http://xml.org/sax/features/namespace-prefixes"; - - /** - * Here namespace processing and namespace-prefixes are enabled. - * The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - - assertTrue(xmlReader.getFeature(NAMESPACES)); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is enabled. This will make namespace-prefixes - * disabled. The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - - XMLReader xmlReader = saxParser.getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACES)); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - - } - - /** - * Here namespace processing is disabled. This will make namespace-prefixes - * enabled. The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACES)); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is disabled, and namespace-prefixes is - * disabled. This will make namespace processing on.The testcase tests - * XMLReader for this. This behavior only apply to crimson, not - * xerces - */ - @Test - public void xrNSTable04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, false); - - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing and namespace-prefixes are enabled. - * The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature(NAMESPACE_PREFIXES,true); - assertTrue(spf.getFeature(NAMESPACES)); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is enabled. This will make namespace-prefixes - * disabled. The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - assertTrue(spf.getFeature(NAMESPACES)); - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is disabled. This will make namespace-prefixes - * enabled. The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(NAMESPACES)); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - /** - * Here namespace processing is disabled, and namespace-prefixes is - * disabled. This will make namespace processing on.The testcase tests - * SAXParserFactory for this. This behavior only apply to crimson, - * not xerces. - */ - @Test - public void spNSTable04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACE_PREFIXES, false); - - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } -} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java index 0453edc186e..f7ee1e92192 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,8 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -35,7 +33,6 @@ import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.ParserAdapter; import org.xml.sax.helpers.XMLFilterImpl; @@ -47,7 +44,7 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * Unit test cases for ParserAdapter API. By default the only features recognized * are namespaces and namespace-prefixes. */ -public class ParserAdapterTest { +public class ParserAdapterTest extends JAXPFileReadOnlyBaseTest { /** * namespaces feature name. */ @@ -67,10 +64,9 @@ public class ParserAdapterTest { /** * Initiate ParserAdapter. - * @throws ParserConfigurationException - * @throws SAXException + * @throws Exception If any errors occur. */ - ParserAdapterTest() throws ParserConfigurationException, SAXException { + ParserAdapterTest() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); XMLReaderAdapter xmlReaderAdapter = new XMLReaderAdapter(xmlReader); @@ -151,129 +147,111 @@ public class ParserAdapterTest { /** * parserAdapter.getFeature(NAMESPACES) returns true be default. + * + * @exception Exception If any errors occur. */ @Test - public void getFeature01() { - try { - assertTrue(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature01() throws Exception { + assertTrue(parserAdapter.getFeature(NAMESPACES)); } /** * parserAdapter.getFeature(NAMESPACE_PREFIXES) returns true be default. + * + * @exception Exception If any errors occur. */ @Test - public void getFeature02() { - try { - assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature02() throws Exception { + assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * SAXNotRecognizedException thrown when feature name is not known one. - * @throws org.xml.sax.SAXNotRecognizedException expected Exception + * + * @exception Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void getFeature03() throws SAXNotRecognizedException { - try { - parserAdapter.getFeature("no-meaning-feature"); - } catch (SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature03() throws Exception { + parserAdapter.getFeature("no-meaning-feature"); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature01() { - try { - parserAdapter.setFeature(NAMESPACES, false); - assertFalse(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature01() throws Exception { + parserAdapter.setFeature(NAMESPACES, false); + assertFalse(parserAdapter.getFeature(NAMESPACES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature02() { - try { - parserAdapter.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature02() throws Exception { + parserAdapter.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature03() { - try { - parserAdapter.setFeature(NAMESPACES, true); - assertTrue(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature03() throws Exception { + parserAdapter.setFeature(NAMESPACES, true); + assertTrue(parserAdapter.getFeature(NAMESPACES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature04() { - try { - parserAdapter.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature04() throws Exception { + parserAdapter.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * NPE expected when parsing a null object by ParserAdapter. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - parserAdapter.parse((InputSource)null); - } catch (IOException | SAXException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + parserAdapter.parse((InputSource)null); } /** * SAXException expected when parsing a wrong-formatter XML with ParserAdapter. - * @throws org.xml.sax.SAXException + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class) - public void parse02() throws SAXException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class) + public void parse02() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { InputSource is = new InputSource(fis); parserAdapter.parse(is); - } catch (IOException ex) { - failUnexpected(ex); } } /** * Parse a well-formatter XML with ParserAdapter. + * + * @throws Exception If any errors occur. */ - @Test - public void parse03() { + @Test(groups = {"readLocalFiles"}) + public void parse03() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "correct.xml")) { InputSource is = new InputSource(fis); parserAdapter.parse(is); - } catch (IOException | SAXException ex) { - failUnexpected(ex); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java index 3215b7eec48..38cece57424 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,21 +26,16 @@ import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -48,12 +43,14 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * Entity resolver should be invoked in XML parse. This test verifies parsing * process by checking the output with golden file. */ -public class ResolverTest { +public class ResolverTest extends JAXPFileBaseTest { /** * Unit test for entityResolver setter. + * + * @throws Exception If any errors occur. */ - public void testResolver() { - String outputFile = CLASS_DIR + "EntityResolver.out"; + public void testResolver() throws Exception { + String outputFile = USER_DIR + "EntityResolver.out"; String goldFile = GOLDEN_DIR + "EntityResolverGF.out"; String xmlFile = XML_DIR + "publish.xml"; @@ -64,23 +61,8 @@ public class ResolverTest { xmlReader.setEntityResolver(eResolver); InputSource is = new InputSource(instream); xmlReader.parse(is); - } catch(IOException | SAXException | ParserConfigurationException ex ) { - failUnexpected(ex); - } - // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java index f3e04f1bc79..cb748b65fc6 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,12 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -44,91 +36,64 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * This class contains the testcases to test SAXParser with regard to * Namespace Table defined at http://www.megginson.com/SAX/Java/namespaces.html */ -public class SAXParserNSTableTest { +public class SAXParserNSTableTest extends JAXPFileBaseTest { /** * namespace processing is enabled. namespace-prefix is also is enabled. * So it is a True-True combination. - * The test is to test SAXParser with these conditions + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ @Test - public void testWithTrueTrue() { - String outputFile = CLASS_DIR + "SPNSTableTT.out"; + public void testWithTrueTrue() throws Exception { + String outputFile = USER_DIR + "SPNSTableTT.out"; String goldFile = GOLDEN_DIR + "NSTableTTGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - true); - - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); } + assertTrue(compareWithGold(goldFile, outputFile)); + } /** * namespace processing is enabled. Hence namespace-prefix is - * expected to be automaically off. So it is a True-False combination. - * The test is to test SAXParser with these conditions + * expected to be automatically off. So it is a True-False combination. + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueFalse() { - String outputFile = CLASS_DIR + "SPNSTableTF.out"; + public void testWithTrueFalse() throws Exception { + String outputFile = USER_DIR + "SPNSTableTF.out"; String goldFile = GOLDEN_DIR + "NSTableTFGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * namespace processing is not enabled. Hence namespace-prefix is - * expected to be automaically on. So it is a False-True combination. - * The test is to test SAXParser with these conditions + * expected to be automatically on. So it is a False-True combination. + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithFalseTrue() { - String outputFile = CLASS_DIR + "SPNSTableFT.out"; + public void testWithFalseTrue() throws Exception { + String outputFile = USER_DIR + "SPNSTableFT.out"; String goldFile = GOLDEN_DIR + "NSTableFTGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java index ccc6e81781d..0d8fba825fd 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,14 +26,10 @@ import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.Attributes; import org.xml.sax.InputSource; @@ -42,7 +38,6 @@ import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,45 +45,34 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * Set parent of XMLFilter to XMLReader. Parsing on XML file will invoke XMLFilter * to write to output file. Test verifies output is same as the golden file. */ -public class XMLFilterCBTest { - public void testXMLFilterCB() { - String outputFile = CLASS_DIR + "XMLFilter.out"; +public class XMLFilterCBTest extends JAXPFileBaseTest { + /** + * Test XMLFilter working with XML reader. + * + * @throws Exception If any errors occur. + */ + public void testXMLFilterCB() throws Exception { + String outputFile = USER_DIR + "XMLFilter.out"; String goldFile = GOLDEN_DIR + "XMLFilterGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try (FileInputStream fis = new FileInputStream(xmlFile)){ + try (FileInputStream fis = new FileInputStream(xmlFile); + MyXMLFilter myXmlFilter = new MyXMLFilter(outputFile)){ SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - MyXMLFilter myXmlFilter = new MyXMLFilter(outputFile); myXmlFilter.setParent(xmlReader); - InputSource is = new InputSource(fis); - myXmlFilter.parse(is); - } catch( SAXException | IOException | ParserConfigurationException ex) { - failUnexpected(ex); + myXmlFilter.parse(new InputSource(fis)); } // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + assertTrue(compareWithGold(goldFile, outputFile)); } } /** * Writer XMLFiler which write all tags to output file when event happens. */ -class MyXMLFilter extends XMLFilterImpl{ +class MyXMLFilter extends XMLFilterImpl implements AutoCloseable { /** * FileWriter to write string to output file. */ @@ -278,4 +262,14 @@ class MyXMLFilter extends XMLFilterImpl{ throw new SAXException(ex); } } + + /** + * Close writer handler. + * @throws IOException if any I/O error when close writer handler. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java index bb80d6b895a..52a91ce4f3e 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,14 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -42,7 +38,7 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; /** * Unit test for XMLFilter. */ -public class XMLFilterTest { +public class XMLFilterTest extends JAXPFileReadOnlyBaseTest { /** * name spaces constant. */ @@ -129,139 +125,114 @@ public class XMLFilterTest { /** * By default true is expected get namespaces feature. - * @throws SAXException + * + * @throws Exception If any errors occur. */ @Test - public void getFeature01() throws SAXException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void getFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - assertTrue(xmlFilter.getFeature(NAMESPACES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(xmlReader); + assertTrue(xmlFilter.getFeature(NAMESPACES)); } /** * By default false is expected get namespaces-prefix feature. + * + * @throws Exception If any errors occur. */ @Test - public void getFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void getFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); } /** * SAXNotRecognizedException is expected when get a feature by an invalid * feature name. - * @throws org.xml.sax.SAXNotRecognizedException If the feature - * value can't be assigned or retrieved from the parent. - * @throws org.xml.sax.SAXNotSupportedException When the - * parent recognizes the feature name but - * cannot determine its value at this time. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void getFeature03() throws SAXNotRecognizedException, - SAXNotSupportedException { + public void getFeature03() throws Exception { new XMLFilterImpl().getFeature("no-meaning-feature"); } /** * Set namespaces feature to a value to XMLFilter. it's expected same when * obtain it again. + * + * @throws Exception If any errors occur. */ @Test - public void setFeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void setFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - xmlFilter.setFeature(NAMESPACES, false); - assertFalse(xmlFilter.getFeature(NAMESPACES)); - xmlFilter.setFeature(NAMESPACES, true); - assertTrue(xmlFilter.getFeature(NAMESPACES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + xmlFilter.setFeature(NAMESPACES, false); + assertFalse(xmlFilter.getFeature(NAMESPACES)); + xmlFilter.setFeature(NAMESPACES, true); + assertTrue(xmlFilter.getFeature(NAMESPACES)); } /** * Set namespaces-prefix feature to a value to XMLFilter. it's expected same * when obtain it again. + * + * @throws Exception If any errors occur. */ @Test - public void setFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void setFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - xmlFilter.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - xmlFilter.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + xmlFilter.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); + xmlFilter.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(xmlFilter.getFeature(NAMESPACE_PREFIXES)); } /** * NullPointerException is expected when parse a null InputSource. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - new XMLFilterImpl().parse((InputSource)null); - } catch (IOException | SAXException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + new XMLFilterImpl().parse((InputSource)null); } /** * SAXException is expected when parsing a invalid formatted XML file. - * @throws org.xml.sax.SAXException when parse a incorrect formatted XML - * file. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void parse02() throws SAXException { - XMLFilterImpl xmlFilter = new XMLFilterImpl(); + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void parse02() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { - InputSource is = new InputSource(fis); - xmlFilter.parse(is); - } catch (IOException ex) { - failUnexpected(ex); + new XMLFilterImpl().parse(new InputSource(fis)); } } /** * No exception when parse a normal XML file. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void parse03() { - XMLFilterImpl xmlFilter = new XMLFilterImpl(); + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void parse03() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "correct2.xml")) { - InputSource is = new InputSource(fis); - xmlFilter.parse(is); - } catch (IOException | SAXException ex) { - failUnexpected(ex); + new XMLFilterImpl().parse(new InputSource(fis)); } } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java index 364656fcdc9..fff624d1f34 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; +import java.io.FilePermission; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; @@ -40,7 +39,7 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; /** * Class containing the test cases for XMLReaderAdapter API */ -public class XMLReaderAdapterTest { +public class XMLReaderAdapterTest extends JAXPBaseTest { /** * http://xml.org/sax/features/namespace-prefixes property name. */ @@ -58,60 +57,51 @@ public class XMLReaderAdapterTest { } /** - * To test the constructor that uses XMLReader + * To test the constructor that uses XMLReader. + * + * @throws Exception If any errors occur. */ @Test - public void constructor02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - assertNotNull(new XMLReaderAdapter(xmlReader)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void constructor02() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + assertNotNull(new XMLReaderAdapter(xmlReader)); } /** * To test the parse method. The specification says that this method * will throw an exception if the embedded XMLReader does not support * the http://xml.org/sax/features/namespace-prefixes property. + * + * @throws Exception If any errors occur. */ @Test - public void nsfeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { - xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); - } - - assertTrue(xmlReader.getFeature(NM_PREFIXES_PROPERTY)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + public void nsfeature01() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { + xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); } + assertTrue(xmlReader.getFeature(NM_PREFIXES_PROPERTY)); } /** * To test the parse method. The specification says that this method * will throw an exception if the embedded XMLReader does not support * the http://xml.org/sax/features/namespace-prefixes property. + * + * @throws Exception If any errors occur. */ @Test - public void parse01() { + public void parse01() throws Exception { + setPermissions(new FilePermission(XML_DIR + "/-", "read")); try (FileInputStream fis = new FileInputStream(XML_DIR + "namespace1.xml")) { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); } XMLReaderAdapter xmlRA = new XMLReaderAdapter(xmlReader); - - InputSource is = new InputSource(fis); xmlRA.setDocumentHandler(new HandlerBase()); - xmlRA.parse(is); - } catch (IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + xmlRA.parse(new InputSource(fis)); } + setPermissions(); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java index 8e9eae0fa76..ae5e9215625 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ package org.xml.sax.ptests; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertNotNull; import org.testng.annotations.Test; import org.xml.sax.SAXException; @@ -30,7 +31,7 @@ import org.xml.sax.helpers.XMLReaderFactory; /** * Unit test for XMLReaderFactory.createXMLReader API. */ -public class XMLReaderFactoryTest { +public class XMLReaderFactoryTest extends JAXPBaseTest { /** * No exception expected when create XMLReader by default. * @throws org.xml.sax.SAXException when xml reader creation failed. @@ -48,12 +49,7 @@ public class XMLReaderFactoryTest { */ @Test public void createReader02() throws SAXException { - //Disable this test because this is only work for apache implementation. - /*System.setProperty("org.xml.sax.driver", - "org.apache.xerces.parsers.SAXParser"); - assertNotNull(XMLReaderFactory. - createXMLReader("org.apache.xerces.parsers.SAXParser"));*/ - System.setProperty("org.xml.sax.driver", + setSystemProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser"); assertNotNull(XMLReaderFactory. createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser")); diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java index 396e67bcf96..f9a2be0b069 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,14 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -41,7 +38,7 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; * Namespace Table defined at * http://www.megginson.com/SAX/Java/namespaces.html */ -public class XMLReaderNSTableTest { +public class XMLReaderNSTableTest extends JAXPFileBaseTest { /** * XML file that used to be parsed. */ @@ -55,71 +52,70 @@ public class XMLReaderNSTableTest { /** * namespace processing is enabled. namespace-prefix is also is enabled. * So it is a True-True combination. - * The test is to test XMLReader with these conditions + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueTrue() { - String outputFile = CLASS_DIR + "XRNSTableTT.out"; + public void testWithTrueTrue() throws Exception { + String outputFile = USER_DIR + "XRNSTableTT.out"; String goldFile = GOLDEN_DIR + "NSTableTTGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile);) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * Namespace processing is enabled. Hence namespace-prefix is - * expected to be automaically off. So it is a True-False combination. - * The test is to test XMLReader with these conditions + * expected to be automatically off. So it is a True-False combination. + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueFalse() { - String outputFile = CLASS_DIR + "XRNSTableTF.out"; + public void testWithTrueFalse() throws Exception { + String outputFile = USER_DIR + "XRNSTableTF.out"; String goldFile = GOLDEN_DIR + "NSTableTFGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxParser = spf.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * namespace processing is not enabled. Hence namespace-prefix is * expected to be automaically on. So it is a False-True combination. - * The test is to test XMLReader with these conditions + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithFalseTrue() { - String outputFile = CLASS_DIR + "XRNSTableFT.out"; + public void testWithFalseTrue()throws Exception { + String outputFile = USER_DIR + "XRNSTableFT.out"; String goldFile = GOLDEN_DIR + "NSTableFTGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java index 1ec7dd64275..c01986f4299 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -45,42 +44,43 @@ import static org.xml.sax.ptests.SAXTestConst.XML_DIR; /** * Class containing the test cases for SAXParser API */ -public class XMLReaderTest { +public class XMLReaderTest extends JAXPFileReadOnlyBaseTest { + /** * XML namespaces. */ - private static final String NAMESPACES = - "http://xml.org/sax/features/namespaces"; + private static final String NAMESPACES + = "http://xml.org/sax/features/namespaces"; /** * XML namespaces prefixes. */ - private static final String NAMESPACE_PREFIXES = - "http://xml.org/sax/features/namespace-prefixes"; + private static final String NAMESPACE_PREFIXES + = "http://xml.org/sax/features/namespace-prefixes"; /** * A string intern name. */ - private static final String STRING_INTERNING = - "http://xml.org/sax/features/string-interning"; + private static final String STRING_INTERNING + = "http://xml.org/sax/features/string-interning"; /** * Validation name. */ - private static final String VALIDATION = - "http://xml.org/sax/features/validation"; + private static final String VALIDATION + = "http://xml.org/sax/features/validation"; /** * A general external entities name */ - private static final String EXTERNAL_G_ENTITIES = - "http://xml.org/sax/features/external-general-entities"; + private static final String EXTERNAL_G_ENTITIES + = "http://xml.org/sax/features/external-general-entities"; /** * A external parameter entities name */ - private static final String EXTERNAL_P_ENTITIES = - "http://xml.org/sax/features/external-parameter-entities"; + private static final String EXTERNAL_P_ENTITIES + = "http://xml.org/sax/features/external-parameter-entities"; /** * XML DOM node name. @@ -95,526 +95,444 @@ public class XMLReaderTest { /** * Declare handler name */ - private static final String DECL_HANDLER = - "http://xml.org/sax/properties/declaration-handler"; + private static final String DECL_HANDLER + = "http://xml.org/sax/properties/declaration-handler"; /** * Lexical handler name */ - private static final String LEXICAL_HANDLER = - "http://xml.org/sax/properties/lexical-handler"; + private static final String LEXICAL_HANDLER + = "http://xml.org/sax/properties/lexical-handler"; /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespaces feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespaces feature names. This test case is + * to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespaces feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespaces feature names. This test case is + * to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACES)); } /** * Obtain http://xml.org/sax/features/namespaces feature name after it's * just set. Expect it's same as set value. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(NAMESPACES, true); - assertTrue(xmlReader.getFeature(NAMESPACES)); - xmlReader.setFeature(NAMESPACES, false); - assertFalse(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACES, true); + assertTrue(xmlReader.getFeature(NAMESPACES)); + xmlReader.setFeature(NAMESPACES, false); + assertFalse(xmlReader.getFeature(NAMESPACES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespace-prefixes feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespace-prefixes feature names. This test + * case is to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespace-prefixes feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespace-prefixes feature names. This test + * case is to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * Obtain http://xml.org/sax/features/namespaces-prefixes feature name after * it's just set. Expect it's same as set value. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - xmlReader.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + xmlReader.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureSI01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(STRING_INTERNING)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureSI01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(STRING_INTERNING)); } /** * getFeature with validation feature name returns the value that * setValidation set. + * + * @throws Exception If any errors occur. */ @Test - public void featureV01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); - spf.setValidating(true); - assertTrue(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureV01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); + spf.setValidating(true); + assertTrue(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); } /** - * getFeature returns the value that a feature has been preset as when + * getFeature returns the value that a feature has been preset as when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureV02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void featureV02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(VALIDATION, true); - assertTrue(xmlReader.getFeature(VALIDATION)); - - xmlReader.setFeature(VALIDATION, false); - assertFalse(xmlReader.getFeature(VALIDATION)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + xmlReader.setFeature(VALIDATION, true); + assertTrue(xmlReader.getFeature(VALIDATION)); + xmlReader.setFeature(VALIDATION, false); + assertFalse(xmlReader.getFeature(VALIDATION)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEGE01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEGE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); } /** - * getFeature returns false if a feature has been preset as false when + * getFeature returns false if a feature has been preset as false when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEGE02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(EXTERNAL_G_ENTITIES, false); - assertFalse(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEGE02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(EXTERNAL_G_ENTITIES, false); + assertFalse(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEPE01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEPE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); } /** - * getFeature returns false if a feature has been preset as false when + * getFeature returns false if a feature has been preset as false when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEPE02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(EXTERNAL_P_ENTITIES, false); - assertFalse(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEPE02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(EXTERNAL_P_ENTITIES, false); + assertFalse(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); } /** * getFeature with a unknown feature name throws SAXNotRecognizedException. - * @throws SAXNotRecognizedException If the feature value can't be assigned - * or retrieved. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void featureNE01() throws SAXNotRecognizedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - boolean noMeaningFeature = xmlReader.getFeature("no-meaning-feature"); - } catch(SAXNotRecognizedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureNE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().getFeature("no-meaning-feature"); } /** * No exception expected when set entity resolver as simple entity resolver. + * + * @throws Exception If any errors occur. */ @Test - public void entity01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setEntityResolver(xmlFilter); - assertNotNull(xmlReader.getEntityResolver()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void entity01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setEntityResolver(xmlFilter); + assertEquals(xmlReader.getEntityResolver(), xmlFilter); } /** * No NPE expected when set entity resolver as null. + * + * @throws Exception If any errors occur. */ @Test - public void entity02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setEntityResolver(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void entity02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setEntityResolver(null); } /** * No exception expected when set DTD handler as simple DTD handler. + * + * @throws Exception If any errors occur. */ @Test - public void dtdhandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setDTDHandler(xmlFilter); - assertNotNull(xmlReader.getDTDHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void dtdhandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setDTDHandler(xmlFilter); + assertEquals(xmlReader.getDTDHandler(), xmlFilter); } /** * No NPE expected when set DTD handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void dtdhandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setDTDHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void dtdhandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setDTDHandler(null); } /** * No exception expected when set content handler as simple content handler. + * + * @throws Exception If any errors occur. */ @Test - public void contenthandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setContentHandler(xmlFilter); - assertNotNull(xmlReader.getContentHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void contenthandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setContentHandler(xmlFilter); + assertEquals(xmlReader.getContentHandler(), xmlFilter); } /** * No NPE expected when set content handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void contenthandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setContentHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void contenthandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setContentHandler(null); } /** * No exception expected when set content handler as simple error handler. + * + * @throws Exception If any errors occur. */ @Test - public void errorhandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setErrorHandler(new XMLFilterImpl()); - assertNotNull(xmlReader.getErrorHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void errorhandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setErrorHandler(new XMLFilterImpl()); + assertNotNull(xmlReader.getErrorHandler()); } /** * No NPE expected when set error handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void errorhandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setErrorHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void errorhandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setErrorHandler(null); } /** * Parse a null input source throw NPE. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.parse((InputSource)null); - } catch (SAXException | ParserConfigurationException | IOException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().parse((InputSource) null); } /** * Unit test for parse a error-formatted file. SAXException is expected. - * @throws org.xml.sax.SAXException parsing failed. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class) - public void parse02() throws SAXException { - try (FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")){ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class) + public void parse02() throws Exception { + try (FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - InputSource is = new InputSource(fis); - xmlReader.parse(is); - } catch (ParserConfigurationException | IOException ex) { - failUnexpected(ex); + spf.newSAXParser().getXMLReader().parse(new InputSource(fis)); } } /** * Unit test for parse a well-formatted file. No exception is expected. + * + * @throws Exception If any errors occur. */ - @Test - public void parse03(){ + @Test(groups = {"readLocalFiles"}) + public void parse03() throws Exception { try (FileInputStream fis = new FileInputStream(XML_DIR + "correct2.xml")) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - InputSource is = new InputSource(fis); - xmlReader.parse(is); - } catch (IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + spf.newSAXParser().getXMLReader().parse(new InputSource(fis)); } } /** - * Modified by IBM - * Xerces does not support this feature and it is not mandatory - * @throws org.xml.sax.SAXNotSupportedException + * Modified by IBM Xerces does not support this feature and it is not + * mandatory. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotSupportedException.class) - public void xrProperty01() throws SAXNotSupportedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.getProperty(XML_STRING); - } catch(SAXNotSupportedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.getProperty(XML_STRING); } /** * SAXNotSupportedException thrown if property name is known but no value * assigned to this property. - * @throws org.xml.sax.SAXNotSupportedException when XMLReader recognizes - * the property name but cannot determine its value at this time. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotSupportedException.class) - public void xrProperty02() throws SAXNotSupportedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(DOM_NODE)); - } catch (SAXNotSupportedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(DOM_NODE)); } - /** * XMLReader.getProperty returns null if LEXICAL_HANDLER wasn't set. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(LEXICAL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(LEXICAL_HANDLER)); } /** * XMLReader.getProperty returns null if DECL_HANDLER wasn't set. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(DECL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(DECL_HANDLER)); } /** * XMLReader.setProperty/getProperty for LEXICAL_HANDLER unit test. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty05() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); - xmlReader.setProperty(LEXICAL_HANDLER, myLexicalHandler); - assertNotNull(xmlReader.getProperty(LEXICAL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty05() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); + xmlReader.setProperty(LEXICAL_HANDLER, myLexicalHandler); + assertNotNull(xmlReader.getProperty(LEXICAL_HANDLER)); } /** * XMLReader.setProperty/getProperty for DECL_HANDLER unit test. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty06() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - MyDeclHandler myDeclHandler = new MyDeclHandler(); - xmlReader.setProperty(DECL_HANDLER, myDeclHandler); - assertNotNull(xmlReader.getProperty(DECL_HANDLER)); - } catch (ParserConfigurationException | SAXException ex){ - failUnexpected(ex); - } + public void xrProperty06() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + MyDeclHandler myDeclHandler = new MyDeclHandler(); + xmlReader.setProperty(DECL_HANDLER, myDeclHandler); + assertNotNull(xmlReader.getProperty(DECL_HANDLER)); } } @@ -622,6 +540,7 @@ public class XMLReaderTest { * Simple LexicalHandler that skips every lexical event. */ class MyLexicalHandler implements LexicalHandler { + /** * Report an XML comment anywhere in the document. * @@ -667,8 +586,10 @@ class MyLexicalHandler implements LexicalHandler { * Report the start of DTD declarations, if any. * * @param name The document type name. - * @param publicId The declared public identifier for the external DTD subset. - * @param systemId The declared system identifier for the external DTD subset. + * @param publicId The declared public identifier for the external DTD + * subset. + * @param systemId The declared system identifier for the external DTD + * subset. */ @Override public void startDTD(String name, String publicId, String systemId) { @@ -688,16 +609,17 @@ class MyLexicalHandler implements LexicalHandler { * Simple DeclHandler that skips every DTD declaration event. */ class MyDeclHandler implements DeclHandler { + /** * Report an attribute type declaration. + * * @param eName The name of the associated element. * @param aName The name of the attribute. * @param type A string representing the attribute type. * @param mode A string representing the attribute defaulting mode - * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if - * none of these applies. - * @param value A string representing the attribute's default value, - * or null if there is none. + * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if none of these applies. + * @param value A string representing the attribute's default value, or null + * if there is none. */ @Override public void attributeDecl(String eName, String aName, String type, @@ -706,6 +628,7 @@ class MyDeclHandler implements DeclHandler { /** * Report an element type declaration. + * * @param name The element type name. * @param model The content model as a normalized string. */ @@ -715,10 +638,11 @@ class MyDeclHandler implements DeclHandler { /** * Report a parsed external entity declaration. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%'. - * @param publicId The entity's public identifier, or null if none - * was given. + * + * @param name The name of the entity. If it is a parameter entity, the name + * will begin with '%'. + * @param publicId The entity's public identifier, or null if none was + * given. * @param systemId The entity's system identifier. */ @Override @@ -728,8 +652,9 @@ class MyDeclHandler implements DeclHandler { /** * Report an internal entity declaration. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%'. + * + * @param name The name of the entity. If it is a parameter entity, the name + * will begin with '%'. * @param value The replacement text of the entity. */ @Override diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java index b21f7f889dc..005828687f5 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,23 +27,18 @@ import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.nio.file.Paths; import java.util.GregorianCalendar; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; - -import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.dom.DOMResult; @@ -51,8 +46,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static jaxp.library.JAXPTestUtilities.bomStream; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import org.testng.annotations.Test; import org.w3c.dom.Attr; import org.w3c.dom.DOMConfiguration; @@ -63,173 +58,160 @@ import org.w3c.dom.TypeInfo; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; -import org.xml.sax.SAXException; import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; import static test.auctionportal.HiBidConstants.XML_DIR; /** * This is the user controller class for the Auction portal HiBid.com. */ -public class AuctionController { +public class AuctionController extends JAXPFileReadOnlyBaseTest { /** * Check for DOMErrorHandler handling DOMError. Before fix of bug 4890927 * DOMConfiguration.setParameter("well-formed",true) throws an exception. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateNewItem2Sell() { + @Test(groups = {"readLocalFiles"}) + public void testCreateNewItem2Sell() throws Exception { String xmlFile = XML_DIR + "novelsInvalid.xml"; - try { - Document document = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(xmlFile); + Document document = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(xmlFile); - document.getDomConfig().setParameter("well-formed", true); + document.getDomConfig().setParameter("well-formed", true); - DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); - DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); - MyDOMOutput domOutput = new MyDOMOutput(); - domOutput.setByteStream(System.out); - LSSerializer writer = impl.createLSSerializer(); - writer.write(document, domOutput); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + MyDOMOutput domOutput = new MyDOMOutput(); + domOutput.setByteStream(System.out); + LSSerializer writer = impl.createLSSerializer(); + writer.write(document, domOutput); } /** * Check for DOMErrorHandler handling DOMError. Before fix of bug 4896132 * test throws DOM Level 1 node error. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateNewItem2SellRetry() { + @Test(groups = {"readLocalFiles"}) + public void testCreateNewItem2SellRetry() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); - DOMConfiguration domConfig = document.getDomConfig(); - MyDOMErrorHandler errHandler = new MyDOMErrorHandler(); - domConfig.setParameter("error-handler", errHandler); + DOMConfiguration domConfig = document.getDomConfig(); + MyDOMErrorHandler errHandler = new MyDOMErrorHandler(); + domConfig.setParameter("error-handler", errHandler); - DOMImplementationLS impl = - (DOMImplementationLS) DOMImplementationRegistry.newInstance() - .getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); - MyDOMOutput domoutput = new MyDOMOutput(); + DOMImplementationLS impl = + (DOMImplementationLS) DOMImplementationRegistry.newInstance() + .getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + MyDOMOutput domoutput = new MyDOMOutput(); - domoutput.setByteStream(System.out); - writer.write(document, domoutput); + domoutput.setByteStream(System.out); + writer.write(document, domoutput); - document.normalizeDocument(); - writer.write(document, domoutput); - assertFalse(errHandler.isError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + document.normalizeDocument(); + writer.write(document, domoutput); + assertFalse(errHandler.isError()); } /** * Check if setting the attribute to be of type ID works. This will affect * the Attr.isID method according to the spec. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateID() { + @Test(groups = {"readLocalFiles"}) + public void testCreateID() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); - Element account = (Element)document - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + Document document = dbf.newDocumentBuilder().parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - account.setIdAttributeNS(PORTAL_ACCOUNT_NS, "accountID", true); - Attr aID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); - assertTrue(aID.isId()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + account.setIdAttributeNS(PORTAL_ACCOUNT_NS, "accountID", true); + Attr aID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(aID.isId()); } /** * Check the user data on the node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckingUserData() { + @Test(groups = {"readLocalFiles"}) + public void testCheckingUserData() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(xmlFile); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(xmlFile); - Element account = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - assertEquals(account.getNodeName(), "acc:Account"); - Element firstName = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); - assertEquals(firstName.getNodeName(), "FirstName"); + Element account = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + assertEquals(account.getNodeName(), "acc:Account"); + Element firstName = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + assertEquals(firstName.getNodeName(), "FirstName"); - Document doc1 = docBuilder.newDocument(); - Element someName = doc1.createElement("newelem"); + Document doc1 = docBuilder.newDocument(); + Element someName = doc1.createElement("newelem"); - someName.setUserData("mykey", "dd", - (operation, key, data, src, dst) -> { - System.err.println("In UserDataHandler" + key); - System.out.println("In UserDataHandler"); - }); - Element impAccount = (Element)document.importNode(someName, true); - assertEquals(impAccount.getNodeName(), "newelem"); - document.normalizeDocument(); - String data = (someName.getUserData("mykey")).toString(); - assertEquals(data, "dd"); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + someName.setUserData("mykey", "dd", + (operation, key, data, src, dst) -> { + System.err.println("In UserDataHandler" + key); + System.out.println("In UserDataHandler"); + }); + Element impAccount = (Element)document.importNode(someName, true); + assertEquals(impAccount.getNodeName(), "newelem"); + document.normalizeDocument(); + String data = (someName.getUserData("mykey")).toString(); + assertEquals(data, "dd"); } /** * Check the UTF-16 XMLEncoding xml file. + * + * @throws Exception If any errors occur. * @see movies.xml */ - @Test - public void testCheckingEncoding() { + @Test(groups = {"readLocalFiles"}) + public void testCheckingEncoding() throws Exception { // Note since movies.xml is UTF-16 encoding. We're not using stanard XML // file suffix. String xmlFile = XML_DIR + "movies.xml.data"; - //try (FileInputStream is = new FileInputStream(xmlFile)) { - try { + try (InputStream source = bomStream("UTF-16", xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - InputStream source = bomStream("UTF-16", xmlFile); Document document = dbf.newDocumentBuilder().parse(source); assertEquals(document.getXmlEncoding(), "UTF-16"); assertEquals(document.getXmlStandalone(), true); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); } } /** * Check validation API features. A schema which is including in Bug 4909119 * used to be testing for the functionalities. + * + * @throws Exception If any errors occur. * @see userDetails.xsd */ - @Test - public void testGetOwnerInfo() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerInfo() throws Exception { String schemaFile = XML_DIR + "userDetails.xsd"; String xmlFile = XML_DIR + "userDetails.xml"; - try { + try(FileInputStream fis = new FileInputStream(xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); @@ -244,27 +226,27 @@ public class AuctionController { DocumentBuilder docBuilder = dbf.newDocumentBuilder(); docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(new FileInputStream(xmlFile)); + Document document = docBuilder.parse(fis); DOMResult dResult = new DOMResult(); DOMSource domSource = new DOMSource(document); validator.validate(domSource, dResult); assertFalse(eh.isAnyError()); - } catch (SAXException | ParserConfigurationException | IOException e) { - failUnexpected(e); } } /** * Check grammar caching with imported schemas. + * + * @throws Exception If any errors occur. * @see coins.xsd * @see coinsImportMe.xsd */ - @Test - public void testGetOwnerItemList() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerItemList() throws Exception { String xsdFile = XML_DIR + "coins.xsd"; String xmlFile = XML_DIR + "coins.xml"; - try { + try(FileInputStream fis = new FileInputStream(xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); @@ -278,11 +260,9 @@ public class AuctionController { validator.setErrorHandler(eh); DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new FileInputStream(xmlFile)); + Document document = docBuilder.parse(fis); validator.validate(new DOMSource(document), new DOMResult()); assertFalse(eh.isAnyError()); - } catch (SAXException | ParserConfigurationException | IOException e) { - failUnexpected(e); } } @@ -291,96 +271,88 @@ public class AuctionController { * Check for the same imported schemas but will use SAXParserFactory and try * parsing using the SAXParser. SCHEMA_SOURCE attribute is using for this * test. + * + * @throws Exception If any errors occur. * @see coins.xsd * @see coinsImportMe.xsd */ - @Test - public void testGetOwnerItemList1() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerItemList1() throws Exception { String xsdFile = XML_DIR + "coins.xsd"; String xmlFile = XML_DIR + "coins.xml"; + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(true); + SAXParser sp = spf.newSAXParser(); + sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + sp.setProperty(JAXP_SCHEMA_SOURCE, xsdFile); - SAXParser sp = spf.newSAXParser(); - sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - sp.setProperty(JAXP_SCHEMA_SOURCE, xsdFile); - - MyErrorHandler eh = new MyErrorHandler(); - sp.parse(new File(xmlFile), eh); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + MyErrorHandler eh = new MyErrorHandler(); + sp.parse(new File(xmlFile), eh); + assertFalse(eh.isAnyError()); } /** * Check usage of javax.xml.datatype.Duration class. + * + * @throws Exception If any errors occur. */ - @Test - public void testGetItemDuration() { + @Test(groups = {"readLocalFiles"}) + public void testGetItemDuration() throws Exception { String xmlFile = XML_DIR + "itemsDuration.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); - Element durationElement = (Element) document.getElementsByTagName("sellDuration").item(0); + Element durationElement = (Element) document.getElementsByTagName("sellDuration").item(0); - NodeList childList = durationElement.getChildNodes(); + NodeList childList = durationElement.getChildNodes(); - for (int i = 0; i < childList.getLength(); i++) { - System.out.println("child " + i + childList.item(i)); - } - - Duration duration = DatatypeFactory.newInstance().newDuration("P365D"); - Duration sellDuration = DatatypeFactory.newInstance().newDuration(childList.item(0).getNodeValue()); - assertFalse(sellDuration.isShorterThan(duration)); - assertFalse(sellDuration.isLongerThan(duration)); - assertEquals(sellDuration.getField(DatatypeConstants.DAYS), BigInteger.valueOf(365)); - assertEquals(sellDuration.normalizeWith(new GregorianCalendar(1999, 2, 22)), duration); - - Duration myDuration = sellDuration.add(duration); - assertEquals(myDuration.normalizeWith(new GregorianCalendar(2003, 2, 22)), - DatatypeFactory.newInstance().newDuration("P730D")); - } catch (ParserConfigurationException | DatatypeConfigurationException - | SAXException | IOException e) { - failUnexpected(e); + for (int i = 0; i < childList.getLength(); i++) { + System.out.println("child " + i + childList.item(i)); } + + Duration duration = DatatypeFactory.newInstance().newDuration("P365D"); + Duration sellDuration = DatatypeFactory.newInstance().newDuration(childList.item(0).getNodeValue()); + assertFalse(sellDuration.isShorterThan(duration)); + assertFalse(sellDuration.isLongerThan(duration)); + assertEquals(sellDuration.getField(DatatypeConstants.DAYS), BigInteger.valueOf(365)); + assertEquals(sellDuration.normalizeWith(new GregorianCalendar(1999, 2, 22)), duration); + + Duration myDuration = sellDuration.add(duration); + assertEquals(myDuration.normalizeWith(new GregorianCalendar(2003, 2, 22)), + DatatypeFactory.newInstance().newDuration("P730D")); } /** * Check usage of TypeInfo interface introduced in DOM L3. + * + * @throws Exception If any errors occur. */ - @Test - public void testGetTypeInfo() { + @Test(groups = {"readLocalFiles"}) + public void testGetTypeInfo() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(new MyErrorHandler()); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new MyErrorHandler()); - Document document = docBuilder.parse(xmlFile); - Element userId = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "UserID").item(0); - TypeInfo typeInfo = userId.getSchemaTypeInfo(); - assertTrue(typeInfo.getTypeName().equals("nonNegativeInteger")); - assertTrue(typeInfo.getTypeNamespace().equals(W3C_XML_SCHEMA_NS_URI)); + Document document = docBuilder.parse(xmlFile); + Element userId = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "UserID").item(0); + TypeInfo typeInfo = userId.getSchemaTypeInfo(); + assertTrue(typeInfo.getTypeName().equals("nonNegativeInteger")); + assertTrue(typeInfo.getTypeNamespace().equals(W3C_XML_SCHEMA_NS_URI)); - Element role = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Role").item(0); - TypeInfo roletypeInfo = role.getSchemaTypeInfo(); - assertTrue(roletypeInfo.getTypeName().equals("BuyOrSell")); - assertTrue(roletypeInfo.getTypeNamespace().equals(PORTAL_ACCOUNT_NS)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + Element role = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Role").item(0); + TypeInfo roletypeInfo = role.getSchemaTypeInfo(); + assertTrue(roletypeInfo.getTypeName().equals("BuyOrSell")); + assertTrue(roletypeInfo.getTypeNamespace().equals(PORTAL_ACCOUNT_NS)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java index ed03442ce9e..8fe1efa3598 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,39 +30,31 @@ import static org.testng.Assert.assertTrue; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; - import org.testng.annotations.Test; import org.w3c.dom.Document; -import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import static test.auctionportal.HiBidConstants.CLASS_DIR; import static test.auctionportal.HiBidConstants.GOLDEN_DIR; import static test.auctionportal.HiBidConstants.XML_DIR; /** * This is a test class for the Auction portal HiBid.com. */ -public class AuctionItemRepository { +public class AuctionItemRepository extends JAXPFileBaseTest { /** * XML file for parsing. */ @@ -78,94 +70,92 @@ public class AuctionItemRepository { * document that has more than two levels of entity expansion is parsed or * not. Previous system property was changed to jdk.xml.entityExpansionLimit * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + * + * @throws Exception If any errors occur. */ @Test - public void testEntityExpansionSAXPos() { - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - // Secure processing will limit XML processing to conform to - // implementation limits. - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - // Set entityExpansionLimit as 2 should expect fatalError - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); - SAXParser parser = factory.newSAXParser(); + public void testEntityExpansionSAXPos() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect fatalError + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); + SAXParser parser = factory.newSAXParser(); - MyErrorHandler fatalHandler = new MyErrorHandler(); - parser.parse(new File(ENTITY_XML), fatalHandler); - assertFalse(fatalHandler.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + MyErrorHandler fatalHandler = new MyErrorHandler(); + setPermissions(new FilePermission(ENTITY_XML, "read")); + parser.parse(new File(ENTITY_XML), fatalHandler); + assertFalse(fatalHandler.isAnyError()); } /** * Setting the EntityExpansion Limit to 2 and checks if the XML * document that has more than two levels of entity expansion is parsed or * not. Previous system property was changed to jdk.xml.entityExpansionLimit * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXParseException.class) - public void testEntityExpansionSAXNeg() throws SAXParseException { - // - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - // Secure processing will limit XML processing to conform to - // implementation limits. - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - // Set entityExpansionLimit as 2 should expect SAXParseException - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - SAXParser parser = factory.newSAXParser(); + public void testEntityExpansionSAXNeg() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect SAXParseException. + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - MyErrorHandler fatalHandler = new MyErrorHandler(); - parser.parse(new File(ENTITY_XML), fatalHandler); - } catch (SAXParseException e) { - throw e; - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + SAXParser parser = factory.newSAXParser(); + MyErrorHandler fatalHandler = new MyErrorHandler(); + setPermissions(new FilePermission(ENTITY_XML, "read")); + parser.parse(new File(ENTITY_XML), fatalHandler); } /** * Testing set MaxOccursLimit to 10000 in the secure processing enabled for * SAXParserFactory. + * + * @throws Exception If any errors occur. */ @Test - public void testMaxOccurLimitPos() { + public void testMaxOccurLimitPos() throws Exception { String schema_file = XML_DIR + "toys.xsd"; String xml_file = XML_DIR + "toys.xml"; - + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(true); + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); + SAXParser parser = factory.newSAXParser(); + parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + setPermissions(new FilePermission(XML_DIR + "-", "read")); + parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); try (InputStream is = new FileInputStream(xml_file)) { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setValidating(true); - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); - SAXParser parser = factory.newSAXParser(); - parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); MyErrorHandler eh = new MyErrorHandler(); parser.parse(is, eh); assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); } } /** * Use a DocumentBuilder to create a DOM object and see if Secure Processing * feature affects the entity expansion. + * + * @throws Exception If any errors occur. */ @Test - public void testEntityExpansionDOMPos() { + public void testEntityExpansionDOMPos() throws Exception { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); try { - DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); - dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); - DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - dBuilder.setErrorHandler(eh); + setPermissions(new FilePermission(ENTITY_XML, "read")); dBuilder.parse(ENTITY_XML); assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); + } finally { + setPermissions(); } } @@ -173,310 +163,209 @@ public class AuctionItemRepository { * Use a DocumentBuilder to create a DOM object and see how does the Secure * Processing feature and entityExpansionLimit value affects output. * Negative test that when entityExpansionLimit is too small. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXParseException.class) - public void testEntityExpansionDOMNeg() throws SAXParseException { - try { - DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); - dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - dBuilder.setErrorHandler(eh); - dBuilder.parse(ENTITY_XML); - } catch (SAXParseException e) { - throw e; - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } + public void testEntityExpansionDOMNeg() throws Exception { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); + setPermissions(new FilePermission(ENTITY_XML, "read")); + dBuilder.parse(ENTITY_XML); } /** * Test xi:include with a SAXParserFactory. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeSAXPos() { - String resultFile = CLASS_DIR + "doc_xinclude.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeSAXPos() throws Exception { + String resultFile = USER_DIR + "doc_xinclude.out"; String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; String xmlFile = XML_DIR + "doc_xinclude.xml"; - try { - try(FileOutputStream fos = new FileOutputStream(resultFile)) { - XInclHandler xh = new XInclHandler(fos, null); - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setXIncludeAware(true); - spf.setFeature(FEATURE_NAME, true); - spf.newSAXParser().parse(new File(xmlFile), xh); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try(FileOutputStream fos = new FileOutputStream(resultFile)) { + XInclHandler xh = new XInclHandler(fos, null); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + spf.newSAXParser().parse(new File(xmlFile), xh); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the simple case of including a document using xi:include using a * DocumentBuilder. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeDOMPos() { - String resultFile = CLASS_DIR + "doc_xincludeDOM.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeDOMPos() throws Exception { + String resultFile = USER_DIR + "doc_xincludeDOM.out"; String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; String xmlFile = XML_DIR + "doc_xinclude.xml"; - try { - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - - TransformerFactory.newInstance().newTransformer(). - transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer(). + transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the simple case of including a document using xi:include within a * xi:fallback using a DocumentBuilder. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeFallbackDOMPos() { - String resultFile = CLASS_DIR + "doc_fallbackDOM.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeFallbackDOMPos() throws Exception { + String resultFile = USER_DIR + "doc_fallbackDOM.out"; String goldFile = GOLDEN_DIR + "doc_fallbackGold.xml"; String xmlFile = XML_DIR + "doc_fallback.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test for xi:fallback where the fall back text is parsed as text. This * test uses a nested xi:include for the fallback test. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeFallbackTextPos() { - String resultFile = CLASS_DIR + "doc_fallback_text.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeFallbackTextPos() throws Exception { + String resultFile = USER_DIR + "doc_fallback_text.out"; String goldFile = GOLDEN_DIR + "doc_fallback_textGold.xml"; String xmlFile = XML_DIR + "doc_fallback_text.xml"; + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the XPointer element() framework with XInclude. + * + * @throws Exception If any errors occur. */ - @Test - public void testXpointerElementPos() { - String resultFile = CLASS_DIR + "doc_xpointer_element.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXpointerElementPos() throws Exception { + String resultFile = USER_DIR + "doc_xpointer_element.out"; String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; String xmlFile = XML_DIR + "doc_xpointer_element.xml"; + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); - DocumentBuilder db = dbf.newDocumentBuilder(); - - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(db.parse(new File(xmlFile))), - new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(db.parse(new File(xmlFile))), + new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the XPointer framework with a SAX object. + * + * @throws Exception If any errors occur. */ - @Test - public void testXPointerPos() { - String resultFile = CLASS_DIR + "doc_xpointer.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXPointerPos() throws Exception { + String resultFile = USER_DIR + "doc_xpointer.out"; String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; String xmlFile = XML_DIR + "doc_xpointer.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setXIncludeAware(true); - spf.setFeature(FEATURE_NAME, true); - // parse the file - spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + // parse the file + spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test if xi:include may reference the doc containing the include if the * parse type is text. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeLoopPos() { - String resultFile = CLASS_DIR + "doc_xinc_loops.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeLoopPos() throws Exception { + String resultFile = USER_DIR + "doc_xinc_loops.out"; String goldFile = GOLDEN_DIR + "doc_xinc_loopGold.xml"; String xmlFile = XML_DIR + "doc_xinc_loops.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document doc = db.parse(new File(xmlFile)); - doc.normalizeDocument(); - doc.setXmlStandalone(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(new File(xmlFile)); + doc.normalizeDocument(); + doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test if two non nested xi:include elements can include the same document * with an xi:include statement. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeNestedPos() { - String resultFile = CLASS_DIR + "schedule.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeNestedPos() throws Exception { + String resultFile = USER_DIR + "schedule.out"; String goldFile = GOLDEN_DIR + "scheduleGold.xml"; String xmlFile = XML_DIR + "schedule.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java index 548dd25b298..6236668ce8b 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,17 @@ package test.auctionportal; import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; import static org.testng.Assert.assertFalse; import java.io.FileOutputStream; -import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; - import org.testng.annotations.Test; import org.w3c.dom.Attr; import org.w3c.dom.Document; @@ -50,8 +46,6 @@ import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSParser; import org.w3c.dom.ls.LSSerializer; -import org.xml.sax.SAXException; -import static test.auctionportal.HiBidConstants.CLASS_DIR; import static test.auctionportal.HiBidConstants.GOLDEN_DIR; import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; import static test.auctionportal.HiBidConstants.XML_DIR; @@ -59,141 +53,127 @@ import static test.auctionportal.HiBidConstants.XML_DIR; /** * This is the user controller class for the Auction portal HiBid.com. */ -public class UserController { +public class UserController extends JAXPFileBaseTest { /** * Checking when creating an XML document using DOM Level 2 validating * it without having a schema source or a schema location It must throw a * sax parse exception. + * + * @throws Exception If any errors occur. */ @Test - public void testCreateNewUser() { - String resultFile = CLASS_DIR + "accountInfoOut.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + public void testCreateNewUser() throws Exception { + String resultFile = USER_DIR + "accountInfoOut.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - Document document = docBuilder.newDocument(); + Document document = docBuilder.newDocument(); - Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account"); - Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID"); - account.setAttributeNode(accountID); + Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account"); + Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID"); + account.setAttributeNode(accountID); - account.appendChild(document.createElement("FirstName")); - account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName")); - account.appendChild(document.createElement("UserID")); + account.appendChild(document.createElement("FirstName")); + account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName")); + account.appendChild(document.createElement("UserID")); - DOMImplementationLS impl - = (DOMImplementationLS) DOMImplementationRegistry - .newInstance().getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); - LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); - FileOutputStream output = new FileOutputStream(resultFile); + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + try(FileOutputStream output = new FileOutputStream(resultFile)) { MyDOMOutput domOutput = new MyDOMOutput(); - domOutput.setByteStream(output); writer.write(account, domOutput); docBuilder.parse(resultFile); - - assertTrue(eh.isAnyError()); - } catch (ParserConfigurationException | ClassNotFoundException | - InstantiationException | IllegalAccessException - | ClassCastException | SAXException | IOException e) { - failUnexpected(e); } + assertTrue(eh.isAnyError()); } /** * Checking conflicting namespaces and use renameNode and normalizeDocument. * @see accountInfo.xml + * + * @throws Exception If any errors occur. */ @Test - public void testAddUser() { - String resultFile = CLASS_DIR + "accountRole.out"; + public void testAddUser() throws Exception { + String resultFile = USER_DIR + "accountRole.out"; String xmlFile = XML_DIR + "accountInfo.xml"; - try { - // Copy schema for outputfile - Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), - Paths.get(CLASS_DIR, "accountInfo.xsd"), - StandardCopyOption.REPLACE_EXISTING); - MyErrorHandler eh = new MyErrorHandler(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + // Copy schema for outputfile + Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), + Paths.get(USER_DIR, "accountInfo.xsd"), + StandardCopyOption.REPLACE_EXISTING); + MyErrorHandler eh = new MyErrorHandler(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(eh); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(xmlFile); - Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0); - Element role = (Element) sell.getParentNode(); + Document document = docBuilder.parse(xmlFile); + Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0); + Element role = (Element) sell.getParentNode(); - Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy"); - role.appendChild(buy); + Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy"); + role.appendChild(buy); - DOMImplementationLS impl - = (DOMImplementationLS) DOMImplementationRegistry - .newInstance().getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); - try(FileOutputStream output = new FileOutputStream(resultFile)) { - MyDOMOutput mydomoutput = new MyDOMOutput(); - mydomoutput.setByteStream(output); - writer.write(document, mydomoutput); - } - - docBuilder.parse(resultFile); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); + try(FileOutputStream output = new FileOutputStream(resultFile)) { + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(output); + writer.write(document, mydomoutput); } + + docBuilder.parse(resultFile); + assertFalse(eh.isAnyError()); } /** * Checking Text content in XML file. * @see accountInfo.xml + * + * @throws Exception If any errors occur. */ - @Test - public void testMoreUserInfo() { + @Test(groups = {"readLocalFiles"}) + public void testMoreUserInfo() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - try { - System.out.println("Checking additional user info"); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + Document document = docBuilder.parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + String textContent = account.getTextContent(); + assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6)); + assertEquals(textContent, "RachelGreen744"); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); + Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(accountID.getTextContent().trim().equals("1")); - Document document = docBuilder.parse(xmlFile); - Element account = (Element)document - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - String textContent = account.getTextContent(); - assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6)); - assertEquals(textContent, "RachelGreen744"); - - Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); - assertTrue(accountID.getTextContent().trim().equals("1")); - - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + assertFalse(eh.isAnyError()); } /** @@ -204,83 +184,73 @@ public class UserController { * into an XML file which is validated by the schema This covers Row 5 * for the table * http://javaweb.sfbay/~jsuttor/JSR206/jsr-206-html/ch03s05.html. Filed - * bug 4893745 because there was a difference in behavior + * bug 4893745 because there was a difference in behavior. + * + * @throws Exception If any errors occur. */ @Test - public void testCreateUserAccount() { - System.out.println("Creating user account"); + public void testCreateUserAccount() throws Exception { String userXmlFile = XML_DIR + "userInfo.xml"; String accountXmlFile = XML_DIR + "accountInfo.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); + Document document = docBuilder.parse(userXmlFile); + Element user = (Element) document.getElementsByTagName("FirstName").item(0); + // Set schema after parsing userInfo.xml. Otherwise it will conflict + // with DTD validation. + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + DocumentBuilder docBuilder1 = dbf.newDocumentBuilder(); + docBuilder1.setErrorHandler(eh); + Document accDocument = docBuilder1.parse(accountXmlFile); - Document document = docBuilder.parse(userXmlFile); - Element user = (Element) document.getElementsByTagName("FirstName").item(0); - // Set schema after parsing userInfo.xml. Otherwise it will conflict - // with DTD validation. - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - DocumentBuilder docBuilder1 = dbf.newDocumentBuilder(); - docBuilder1.setErrorHandler(eh); - Document accDocument = docBuilder1.parse(accountXmlFile); + Element firstName = (Element) accDocument + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + Element adoptedAccount = (Element) accDocument.adoptNode(user); - Element firstName = (Element) accDocument - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); - Element adoptedAccount = (Element) accDocument.adoptNode(user); + Element parent = (Element) firstName.getParentNode(); + parent.replaceChild(adoptedAccount, firstName); - Element parent = (Element) firstName.getParentNode(); - parent.replaceChild(adoptedAccount, firstName); + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); - DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); - DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(System.out); - MyDOMOutput mydomoutput = new MyDOMOutput(); - mydomoutput.setByteStream(System.out); + writer.write(document, mydomoutput); + writer.write(accDocument, mydomoutput); - writer.write(document, mydomoutput); - writer.write(accDocument, mydomoutput); - - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + assertFalse(eh.isAnyError()); } /** * Checking for Row 8 from the schema table when setting the schemaSource * without the schemaLanguage must report an error. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testUserError() throws IllegalArgumentException { - System.out.println("Creating an error in user account"); - + public void testUserError() throws Exception { String xmlFile = XML_DIR + "userInfo.xml"; String schema = "http://java.sun.com/xml/jaxp/properties/schemaSource"; String schemaValue = "http://dummy.com/dummy.xsd"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); - dbf.setAttribute(schema, schemaValue); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(schema, schemaValue); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(xmlFile); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + docBuilder.parse(xmlFile); + assertFalse(eh.isAnyError()); } /** @@ -288,10 +258,12 @@ public class UserController { * @see screenName.xml has prefix of * userName is bound to "http://hibid.com/user" namespace normalization * will create a namespace of prefix us and attach userEmail. + * + * @throws Exception If any errors occur. */ @Test - public void testCheckScreenNameExists() { - String resultFile = CLASS_DIR + "screenName.out"; + public void testCheckScreenNameExists() throws Exception { + String resultFile = USER_DIR + "screenName.out"; String xmlFile = XML_DIR + "screenName.xml"; String goldFile = GOLDEN_DIR + "screenNameGold.xml"; @@ -318,21 +290,7 @@ public class UserController { MyDOMOutput domoutput = new MyDOMOutput(); domoutput.setByteStream(output); writer.write(document, domoutput); - - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException | IOException - | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } } diff --git a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java similarity index 83% rename from jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java rename to jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java index 9f8dc355333..c43390d43b9 100644 --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,37 +22,22 @@ */ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.ERROR_MSG_HEADER; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; - import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; - +import static jaxp.library.JAXPTestUtilities.ERROR_MSG_HEADER; import org.xml.sax.Attributes; import org.xml.sax.Locator; -import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.LocatorImpl; -/** - * Utility interface which includes final variables of xml, golden file - * directories. - */ -interface TestUtils { - final String XML_DIR = System.getProperty("test.src", ".") + FILE_SEP + "javax/xml/parsers/xmlfiles"; - final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out"; -} - /** * Customized DefaultHandler which writes output document when methods are * called by Transformer. Test may use output document to compare with golden * file for verification. */ -class MyCHandler extends DefaultHandler { +class MyCHandler extends DefaultHandler implements AutoCloseable { private final BufferedWriter bWriter; private final Locator locator = new LocatorImpl(); @@ -66,6 +51,7 @@ class MyCHandler extends DefaultHandler { return handler; } + @Override public void characters(char[] ch, int start, int length) { String s = new String(ch, start, length); String str = String.format("characters...length is:%d\n<%s>", s.length(), s); @@ -77,19 +63,19 @@ class MyCHandler extends DefaultHandler { } } + @Override public void endDocument() { String str = "endDocument..."; try { bWriter.write(str, 0, str.length()); bWriter.newLine(); bWriter.flush(); - bWriter.close(); - } catch (IOException e) { throw new RuntimeException(ERROR_MSG_HEADER, e); } } + @Override public void endElement(String namespaceURI, String localName, String qName) { String str = String.format("endElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s>", namespaceURI, localName, qName); try { @@ -100,6 +86,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void endPrefixMapping(String prefix) { String str = String.format("endPrefixMapping...\nprefix: <%s>", prefix); try { @@ -110,6 +97,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void ignorableWhitespace(char[] ch, int start, int length) { String s = new String(ch, start, length); String str = String.format("ignorableWhitespace...\n%s ignorable white space string length: %d", s, s.length()); @@ -121,6 +109,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void processingInstruction(String target, String data) { String str = String.format("processingInstruction...target:<%s> data: <%s>", target, data); try { @@ -131,6 +120,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void skippedEntity(String name) { String str = String.format("skippedEntity...\nname: <%s>", name); try { @@ -141,6 +131,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void startDocument() { String str = "startDocument..."; try { @@ -151,6 +142,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { String str = String.format("startElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s> Number of Attributes: <%d> Line# <%d>", namespaceURI, localName, qName, atts.getLength(), locator.getLineNumber()); @@ -162,6 +154,7 @@ class MyCHandler extends DefaultHandler { } } + @Override public void startPrefixMapping(String prefix, String uri) { String str = String.format("startPrefixMapping...\nprefix: <%s> uri: <%s>", prefix, uri); try { @@ -171,30 +164,10 @@ class MyCHandler extends DefaultHandler { throw new RuntimeException(ERROR_MSG_HEADER, e); } } -} -/** - * Customized DefaultHandler used for SAXParseException testing. - */ -class MyErrorHandler extends DefaultHandler { - boolean errorOccured = false; - - private MyErrorHandler() { - } - - public static MyErrorHandler newInstance() { - return new MyErrorHandler(); - } - - public void error(SAXParseException e) { - errorOccured = true; - } - - public void warning(SAXParseException e) { - errorOccured = true; - } - - public void fatalError(SAXParseException e) { - errorOccured = true; + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); } } diff --git a/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java new file mode 100644 index 00000000000..2910a6edef0 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.xml.parsers.ptests; + +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Customized DefaultHandler used for SAXParseException testing. + */ +class MyErrorHandler extends DefaultHandler { + /** + * Flag whether any event was received. + */ + private volatile boolean errorOccured; + + /** + * Set no event received on constructor. + */ + private MyErrorHandler() { + errorOccured = false; + } + + /** + * Factory method to create a MyErrorHandler instance. + * @return a MyErrorHandler instance. + */ + public static MyErrorHandler newInstance() { + return new MyErrorHandler(); + } + + /** + * Receive notification of a recoverable error. + * @param e a recoverable parser exception error. + */ + @Override + public void error(SAXParseException e) { + errorOccured = true; + } + + /** + * Receive notification of a parser warning. + * @param e a parser warning event. + */ + @Override + public void warning(SAXParseException e) { + errorOccured = true; + } + + /** + * Report a fatal XML parsing error. + * @param e The error information encoded as an exception. + */ + @Override + public void fatalError(SAXParseException e) { + errorOccured = true; + } + + /** + * Has any event been received. + * + * @return true if any event has been received. + * false if no event has been received. + */ + public boolean isErrorOccured() { + return errorOccured; + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java new file mode 100644 index 00000000000..ac50221fec8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.xml.parsers.ptests; + +import static jaxp.library.JAXPTestUtilities.FILE_SEP; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; + + +/** + * Utility interface which includes final variables of XML, golden file + * directories. + */ +public class ParserTestConst { + /** + * XML source file directory. + */ + public static final String XML_DIR = getPathByClassName(ParserTestConst.class, + ".." + FILE_SEP + "xmlfiles"); + + + /** + * Golden validation files directory. + */ + public static final String GOLDEN_DIR = getPathByClassName(ParserTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); +} diff --git a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java index 898e008097d..f08d5f57546 100644 --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java index df40a8c78c4..5f119360432 100644 --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,40 +23,22 @@ package javax.xml.transform.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for JAXP functional test */ public class TransformerTestConst { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; + public static final String XML_DIR = getPathByClassName(TransformerTestConst.class, + ".." + FILE_SEP + "xmlfiles"); + /** - * Package name that separates by slash. + * Golden validation files directory. */ - public static final String PACKAGE_NAME = FILE_SEP + - TransformerTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - - /** - * Test base directory. Every package has its own test package directory. - */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. - */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; - - /** - * Golden output file directory. We pre-define all expected output in golden - * output file. Test verifies whether the standard output is same as content - * of golden file. - */ - public static final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(TransformerTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); } diff --git a/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java b/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java index 719d6712645..605dada1656 100644 --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,27 +23,15 @@ package javax.xml.xpath.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for XPath functional test */ public class XPathTestConst { /** - * Package name that separates by slash. + * XML source file directory. */ - public static final String PACKAGE_NAME = FILE_SEP + - XPathTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - - /** - * Test base directory. Every package has its own test package directory. - */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. - */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; + public static final String XML_DIR = getPathByClassName(XPathTestConst.class, + ".." + FILE_SEP + "xmlfiles"); } diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java new file mode 100644 index 00000000000..687ff7009d5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.security.Permission; +import java.security.Permissions; +import java.security.Policy; +import java.util.PropertyPermission; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +/** + * This is a base class that every test class must extend if it needs to be run + * with security mode. + */ +public class JAXPBaseTest { + /** + * Backing up policy. + */ + protected static Policy policy; + + /** + * Backing up security manager. + */ + private static SecurityManager sm; + + /* + * Install a SecurityManager along with a base Policy to allow testNG to + * run when there is a security manager. + */ + @BeforeClass + public void setUpClass() throws Exception { + setPolicy(new TestPolicy()); + System.setSecurityManager(new SecurityManager()); + } + + /* + * Install the original Policy and SecurityManager when there is a security + * manager. + */ + @AfterClass + public void tearDownClass() throws Exception { + System.setSecurityManager(sm); + setPolicy(policy); + } + + /* + * Utility Method used to set the current Policy. + */ + protected static void setPolicy(Policy p) { + Policy.setPolicy(p); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permission... ps) { + Policy.setPolicy(new TestPolicy(ps)); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permissions ps) { + Policy.setPolicy(new TestPolicy(ps)); + } + + /** + * Backing up policy and security manager for restore when there is a + * security manager. + */ + public JAXPBaseTest() { + policy = Policy.getPolicy(); + sm = System.getSecurityManager(); + } + + /** + * Safety acquire a system property. + * Note invocation of this method will restore permission to limited + * minimal permission of tests. If there is additional permission set + * already, you need restore permission by yourself. + * @param propName System property name to be acquired. + * @return property value + */ + protected String getSystemProperty(final String propName) { + setPermissions(new PropertyPermission(propName, "read")); + try { + return System.getProperty(propName); + } finally { + setPermissions(); + } + } + + /** + * Safety set a system property by given system value. + * + * @param propName System property name to be set. + * @param propValue System property value to be set. + */ + protected void setSystemProperty(final String propName, final String propValue) { + setPermissions(new PropertyPermission(propName, "write")); + try { + if (propValue == null) { + System.clearProperty(propName); + } else { + System.setProperty(propName, propValue); + } + } finally { + setPermissions(); + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java new file mode 100644 index 00000000000..c45c6d3a270 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.io.FilePermission; +import java.security.Permission; +import java.security.Permissions; +import java.security.Policy; +import static jaxp.library.JAXPBaseTest.setPolicy; +import org.testng.annotations.BeforeClass; + +/** + * This is a base class that every test class that need to access local XML + * files must extend if it needs to be run with security mode. + */ +public class JAXPFileBaseTest extends JAXPBaseTest { + /* + * Install a SecurityManager along with a base Policy to allow testNG to + * run when there is a security manager. + */ + @BeforeClass + @Override + public void setUpClass() throws Exception { + setPolicy(new FileTestPolicy()); + System.setSecurityManager(new SecurityManager()); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permission... ps) { + Policy.setPolicy(new FileTestPolicy(ps)); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permissions ps) { + Policy.setPolicy(new FileTestPolicy(ps)); + } +} + +/** + * This policy is only given to tests that need access local files. Additional + * permissions for accessing local files have been granted by default. + * @author HaiboYan + */ +class FileTestPolicy extends TestPolicy { + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + * @param ps permissions to be added. + */ + public FileTestPolicy(Permissions ps) { + super(ps); + } + + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + * @param ps permission array to be added. + */ + public FileTestPolicy(Permission... ps) { + super(ps); + } + + /** + * Defines the minimal permissions required by testNG when running these + * tests + */ + @Override + protected void setMinimalPermissions() { + super.setMinimalPermissions(); + permissions.add(new FilePermission(System.getProperty("user.dir") + "/-", + "read, write")); + permissions.add(new FilePermission(System.getProperty("test.src") + "/-", + "read")); + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java new file mode 100644 index 00000000000..eed9a05b784 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.io.FilePermission; +import static jaxp.library.JAXPBaseTest.setPermissions; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; + +/** + * This is a base class that every test class that need to reading local XML + * files must extend if it needs to be run with security mode. + */ +public class JAXPFileReadOnlyBaseTest extends JAXPBaseTest { + /** + * Source files/XML files directory. + */ + private final String SRC_DIR = getSystemProperty("test.src"); + + /** + * Allowing access local file system for this group. + */ + @BeforeGroups (groups = {"readLocalFiles"}) + public void setFilePermissions() { + setPermissions(new FilePermission(SRC_DIR + "/-", "read")); + } + + /** + * Restore the system property. + */ + @AfterGroups (groups = {"readLocalFiles"}) + public void restoreFilePermissions() { + setPermissions(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java index 33d0e1c01bc..a7f18083d30 100644 --- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,21 +23,34 @@ package jaxp.library; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import static org.testng.Assert.fail; import org.w3c.dom.Document; +import org.w3c.dom.Node; import org.xml.sax.SAXException; /** @@ -61,14 +74,17 @@ public class JAXPTestUtilities { public static final String FILE_SEP = "/"; /** - * User home. + * Current test directory. */ - public static final String USER_DIR = System.getProperty("user.dir", "."); + public static final String USER_DIR = + System.getProperty("user.dir", ".") + FILE_SEP;; /** - * TEMP file directory. + * A map storing every test's current test file pointer. File number should + * be incremental and it's a thread-safe reading on this file number. */ - public static final String TEMP_DIR = System.getProperty("java.io.tmpdir", "."); + private static final ConcurrentHashMap currentFileNumber + = new ConcurrentHashMap<>(); /** * BOM table for storing BOM header. @@ -94,12 +110,60 @@ public class JAXPTestUtilities { * @return true if two files are identical. * false if two files are not identical. * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read + * malformed or unmappable byte sequence is read. */ public static boolean compareWithGold(String goldfile, String outputfile) throws IOException { + return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); + } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param outputfile Test output file name. + * @param cs the charset to use for decoding. + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile, + Charset cs) throws IOException { return Files.readAllLines(Paths.get(goldfile)). - equals(Files.readAllLines(Paths.get(outputfile))); + equals(Files.readAllLines(Paths.get(outputfile), cs)); + } + + /** + * Compare contents of golden file with test output list line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param lines test output list. + * @return true if file's content is identical to given list. + * false if file's content is not identical to given list. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareLinesWithGold(String goldfile, List lines) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).equals(lines); + } + + /** + * Compare contents of golden file with a test output string. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param string test string. + * @return true if file's content is identical to given string. + * false if file's content is not identical to given string. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareStringWithGold(String goldfile, String string) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).stream().collect( + Collectors.joining(System.getProperty("line.separator"))) + .equals(string); } /** @@ -132,6 +196,35 @@ public class JAXPTestUtilities { resultD.normalizeDocument(); return goldD.isEqualNode(resultD); } + + /** + * Compare contents of golden file with the serialization represent by given + * DOM node. + * Here we ignore the white space and comments. return true if they're + * lexical identical. + * @param goldfile Golden output file name. + * @param node A DOM node instance. + * @return true if file's content is identical to given node's serialization + * represent. + * false if file's content is not identical to given node's + * serialization represent. + * @throws TransformerException If an unrecoverable error occurs during the + * course of the transformation.. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read . + */ + public static boolean compareSerializeDOMWithGold(String goldfile, Node node) + throws TransformerException, IOException { + TransformerFactory factory = TransformerFactory.newInstance(); + // Use identity transformer to serialize + Transformer identityTransformer = factory.newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult streamResult = new StreamResult(sw); + DOMSource nodeSource = new DOMSource(node); + identityTransformer.transform(nodeSource, streamResult); + return compareStringWithGold(goldfile, sw.toString()); + } + /** * Convert stream to ByteArrayInputStream by given character set. * @param charset target character set. @@ -159,6 +252,36 @@ public class JAXPTestUtilities { return new ByteArrayInputStream(bb.array()); } + /** + * Worker method to detect common absolute URLs. + * + * @param s String path\filename or URL (or any, really) + * @return true if s starts with a common URI scheme (namely + * the ones found in the examples of RFC2396); false otherwise + */ + protected static boolean isCommonURL(String s) { + if (null == s) + return false; + return Pattern.compile("^(file:|http:|ftp:|gopher:|mailto:|news:|telnet:)") + .matcher(s).matches(); + } + + /** + * Utility method to translate a String filename to URL. + * + * If the name starts with a common URI scheme (namely the ones + * found in the examples of RFC2396), then simply return the + * name as-is (the assumption is that it's already a URL). + * Otherwise we attempt (cheaply) to convert to a file:/ URL. + * + * @param filename local path/filename of a file. + * @return a file:/ URL if filename represent a file, the same string if + * it appears to already be a URL. + */ + public static String filenameToURL(String filename) { + return Paths.get(filename).toUri().toASCIIString(); + } + /** * Prints error message if an exception is thrown * @param ex The exception is thrown by test. @@ -175,4 +298,38 @@ public class JAXPTestUtilities { public static void failCleanup(IOException ex, String name) { fail(String.format(ERROR_MSG_CLEANUP, name), ex); } + + /** + * Retrieve next test output file name. This method is a thread-safe method. + * @param clazz test class. + * @return next test output file name. + */ + public static String getNextFile(Class clazz) { + int nextNumber = currentFileNumber.contains(clazz) + ? currentFileNumber.get(clazz) + 1 : 1; + Integer i = currentFileNumber.putIfAbsent(clazz, nextNumber); + if (i != null && i != nextNumber) { + do { + nextNumber = currentFileNumber.get(clazz) + 1; + } while (currentFileNumber.replace(clazz, nextNumber -1, nextNumber)); + } + return USER_DIR + clazz.getName() + nextNumber + ".out"; + } + + /** + * Acquire a full path string by given class name and relative path string. + * @param clazz Class name for the test. + * @param relativeDir relative path between java source file and expected + * path. + * @return a string represents the full path of accessing path. + */ + public static String getPathByClassName(Class clazz, String relativeDir) { + String packageName = FILE_SEP + + clazz.getPackage().getName().replaceAll("[.]", FILE_SEP); + String javaSourcePath = System.getProperty("test.src").replaceAll("\\" + File.separator, FILE_SEP) + + packageName + FILE_SEP; + String normalizedPath = Paths.get(javaSourcePath, relativeDir).normalize(). + toAbsolutePath().toString(); + return normalizedPath.replace("\\", FILE_SEP) + FILE_SEP; + } } diff --git a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java new file mode 100644 index 00000000000..1e39fbc36eb --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.security.SecurityPermission; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.PropertyPermission; +import java.util.StringJoiner; + +/* + * Simple Policy class that supports the required Permissions to validate the + * JAXP concrete classes. + * Note: permission can only be added. You may want to create a new TestPolicy + * instance if you need remove permissions. + */ +public class TestPolicy extends Policy { + protected final PermissionCollection permissions = new Permissions(); + + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + */ + public TestPolicy() { + setMinimalPermissions(); + } + + /** + * Construct an instance with the minimal permissions required by the test + * environment and additional permission(s) as specified. + * @param ps permissions to be added. + */ + public TestPolicy(Permissions ps) { + setMinimalPermissions(); + TestPolicy.this.addPermissions(ps); + } + + /** + * Construct an instance with the minimal permissions required by the test + * environment and additional permission(s) as specified. + * @param ps permission array to be added. + */ + public TestPolicy(Permission... ps) { + setMinimalPermissions(); + addPermissions(ps); + } + + /** + * Defines the minimal permissions required by testNG when running these + * tests + */ + protected void setMinimalPermissions() { + permissions.add(new SecurityPermission("getPolicy")); + permissions.add(new SecurityPermission("setPolicy")); + permissions.add(new RuntimePermission("getClassLoader")); + permissions.add(new RuntimePermission("setSecurityManager")); + permissions.add(new RuntimePermission("createSecurityManager")); + permissions.add(new PropertyPermission("testng.show.stack.frames", + "read")); + permissions.add(new PropertyPermission("user.dir", "read")); + permissions.add(new PropertyPermission("test.src", "read")); + permissions.add(new PropertyPermission("file.separator", "read")); + permissions.add(new PropertyPermission("line.separator", "read")); + permissions.add(new PropertyPermission("fileStringBuffer", "read")); + permissions.add(new PropertyPermission("dataproviderthreadcount", "read")); + } + + /* + * Add permissions for your tests. + * @param permissions to be added. + */ + private void addPermissions(Permissions ps) { + Collections.list(ps.elements()).forEach(p -> permissions.add(p)); + } + + + /* + * Add permissions for your tests. + * @param permissions to be added. + */ + private void addPermissions(Permission[] ps) { + Arrays.stream(ps).forEach(p -> permissions.add(p)); + } + + /** + * Set all permissions. Caution: this should not called carefully unless + * it's really needed. + */ + private void setAllPermissions() { + permissions.add(new AllPermission()); + } + + /* + * Overloaded methods from the Policy class. + */ + @Override + public String toString() { + StringJoiner sj = new StringJoiner("\n", "policy: ", ""); + Enumeration perms = permissions.elements(); + while (perms.hasMoreElements()) { + sj.add(perms.nextElement().toString()); + } + return sj.toString(); + + } + + @Override + public PermissionCollection getPermissions(ProtectionDomain domain) { + return permissions; + } + + @Override + public PermissionCollection getPermissions(CodeSource codesource) { + return permissions; + } + + @Override + public boolean implies(ProtectionDomain domain, Permission perm) { + return permissions.implies(perm); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java similarity index 98% rename from jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java rename to jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java index b1f037f6ce5..700c05e22ec 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java similarity index 94% rename from jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java rename to jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java index 1e686630377..af3f219b9b4 100644 --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,11 +31,12 @@ import java.io.IOException; import java.io.FileWriter; import org.xml.sax.SAXException; -class MyNSContentHandler extends DefaultHandler { +class MyNSContentHandler extends DefaultHandler implements AutoCloseable{ /** * Prefix for written string. */ private final static String WRITE_ERROR = "bWrite error"; + /** * FileWriter to write output file. */ @@ -205,4 +206,14 @@ class MyNSContentHandler extends DefaultHandler { throw new SAXException(WRITE_ERROR, ex); } } + + /** + * Close writer if it's initiated. + * @throws IOException if any I/O error when close writer. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } } diff --git a/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java index caac12f8c5a..6798d7879dc 100644 --- a/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package org.xml.sax.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for JAXP SAX functional @@ -32,33 +32,15 @@ import static jaxp.library.JAXPTestUtilities.USER_DIR; */ public class SAXTestConst { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; + public static final String XML_DIR = getPathByClassName(SAXTestConst.class, + ".." + FILE_SEP + "xmlfiles"); + /** - * Package name that separates by slash. + * Golden validation files directory. */ - public static final String PACKAGE_NAME = FILE_SEP + - SAXTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - - /** - * Test base directory. Every package has its own test package directory. - */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. - */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; - - /** - * Golden output file directory. We pre-define all expected output in golden - * output file. Test verifies whether the standard output is same as content - * of golden file. - */ - public static final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(SAXTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); } diff --git a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java index a5dbdb91f71..9ee741b15a1 100644 --- a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,44 +22,21 @@ */ package test.auctionportal; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for Auction portal test. */ public class HiBidConstants { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; + public static final String XML_DIR = getPathByClassName(HiBidConstants.class, "content"); /** - * Package name that separates by slash. + * Golden validation files directory. */ - public static final String PACKAGE_NAME = FILE_SEP + - HiBidConstants.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - - - /** - * Java source directory. - */ - public static final String SRC_DIR = System.getProperty("test.src", USER_DIR) - .replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP; - - /** - * Source XML file directory. - */ - public static final String XML_DIR = SRC_DIR + "content" + FILE_SEP; - - /** - * Golden output file directory. - * We pre-define all expected output in golden output file. Test verifies - * whether the standard output is same as content of golden file. - */ - public static final String GOLDEN_DIR = SRC_DIR + "golden" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(HiBidConstants.class, "golden"); /** * Name space for account operation. diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java similarity index 96% rename from jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java rename to jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java index d0432042199..2ab92f04873 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java similarity index 96% rename from jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java rename to jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java index 9f2e7d3a5e9..64b16ddb1f7 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,7 @@ public class MyDOMOutput implements LSOutput { /** * Set 16 bits unit writable stream. * - * @param bs a Writer instance + * @param cs a Writer instance */ @Override public void setCharacterStream(Writer cs) { diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java similarity index 97% rename from jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java rename to jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java index 0a1580ae517..aae83212bf5 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java similarity index 92% rename from jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java rename to jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java index b8d2bb35fcc..e8de8d878ae 100644 --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,8 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { /** * Sets whether output is canonical. + * + * @param canonical if the output is canonical format. */ public void setCanonical(boolean canonical) { fCanonical = canonical; @@ -66,6 +68,8 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { * Sets the output stream for printing. * @param stream OutputStream for message output. * @param encoding File encoding for message output. + * @throws UnsupportedEncodingException if given encoding is an unsupported + * encoding name or invalid encoding name. */ public XInclHandler(OutputStream stream, String encoding) throws UnsupportedEncodingException { @@ -97,8 +101,8 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { * @param target The processing instruction target. * @param data The processing instruction data, or null if * none is supplied. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. + * @exception SAXException Any SAX exception, possibly wrapping another + * exception. */ @Override public void processingInstruction (String target, String data) @@ -119,14 +123,16 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { * @param uri The Namespace URI, or the empty string if the * element has no Namespace URI or if Namespace * processing is not being performed. - * @param localName The local name (without prefix), or the + * @param local The local name (without prefix), or the * empty string if Namespace processing is not being * performed. - * @param qName The qualified name (with prefix), or the + * @param raw The qualified name (with prefix), or the * empty string if qualified names are not available. - * @param attributes The attributes attached to the element. If + * @param attrs The attributes attached to the element. If * there are no attributes, it shall be an empty * Attributes object. + * @throws SAXException Any SAX exception, possibly wrapping another + * exception. */ @Override public void startElement(String uri, String local, String raw, @@ -181,11 +187,13 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { * @param uri The Namespace URI, or the empty string if the * element has no Namespace URI or if Namespace * processing is not being performed. - * @param localName The local name (without prefix), or the + * @param local The local name (without prefix), or the * empty string if Namespace processing is not being * performed. - * @param qName The qualified name (with prefix), or the + * @param raw The qualified name (with prefix), or the * empty string if qualified names are not available. + * @throws org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. */ @Override public void endElement(String uri, String local, String raw) @@ -196,7 +204,7 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { /** * Receive notification of a parser warning and print it out. - * @param e The warning information encoded as an exception. + * @param ex The warning information encoded as an exception. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. */ @@ -207,10 +215,9 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { /** * Receive notification of a parser error and print it out. - * @param e The error information encoded as an exception. + * @param ex The error information encoded as an exception. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. - */ @Override public void error(SAXParseException ex) throws SAXException { @@ -220,7 +227,7 @@ public class XInclHandler extends DefaultHandler implements LexicalHandler { /** * Receive notification of a parser fatal error. Throw out fatal error * following print fatal error message. - * @param e The fatal error information encoded as an exception. + * @param ex The fatal error information encoded as an exception. * @exception org.xml.sax.SAXException Any SAX exception, possibly * wrapping another exception. From da5d03e7843243ae960271455e9e9d4c33e04b9d Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 16 Jan 2015 10:15:54 +0100 Subject: [PATCH 71/72] 8069041: Bootcycle builds do not work with sjavac Reviewed-by: ihse --- make/common/JavaCompilation.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk index 6c6e515c816..a183b30dead 100644 --- a/make/common/JavaCompilation.gmk +++ b/make/common/JavaCompilation.gmk @@ -538,7 +538,7 @@ define SetupJavaCompilationInner $1_REMOTE:=--server:portfile=$$($1_SJAVAC_PORTFILE),id=$1,sjavac=$$(subst $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_SERVER_JVM) $$($1_SJAVAC)))) $$($1_BIN)/_the.$1_batch: $$($1_SRCS) $$($1_DEPENDS) - $(MKDIR) -p $$(@D) + $(MKDIR) -p $$(@D) $$(dir $$($1_SJAVAC_PORTFILE)) # As a workaround for sjavac not tracking api changed from the classpath, force full # recompile if an external dependency, which is something other than a source # change, triggered this compilation. From 31f50fcff96fdeab57ea15c9830f301b763fa217 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Fri, 16 Jan 2015 12:41:36 +0100 Subject: [PATCH 72/72] 8068736: Avoid synchronization on Executable/Field.declaredAnnotations Reviewed-by: jfranck, psandoz --- .../classes/java/lang/reflect/Executable.java | 35 +++++++++++-------- .../classes/java/lang/reflect/Field.java | 33 ++++++++++------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java index 21c90f41da3..ee82de46946 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -588,22 +588,29 @@ public abstract class Executable extends AccessibleObject return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Executable root = getRoot(); - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - getAnnotationBytes(), - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Executable root = getRoot(); + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + getAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass() + ); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } /** diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java index bb23b22dc94..cb3cbf5e7d0 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1139,21 +1139,28 @@ class Field extends AccessibleObject implements Member { return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Field root = this.root; - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, - sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Field root = this.root; + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + annotations, + sun.misc.SharedSecrets.getJavaLangAccess() + .getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } private native byte[] getTypeAnnotationBytes0();