diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 32f36110423..d10b68389a6 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -341,3 +341,4 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
+7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
diff --git a/common/bin/jib.sh b/common/bin/jib.sh
index 0fc60e9e76f..454d78ce1d7 100644
--- a/common/bin/jib.sh
+++ b/common/bin/jib.sh
@@ -32,7 +32,7 @@ installed_jib_script=${mydir}/../../.jib/jib
install_data=${mydir}/../../.jib/.data
setup_url() {
- if [ -f "~/.config/jib/jib.conf" ]; then
+ if [ -f ~/.config/jib/jib.conf ]; then
source ~/.config/jib/jib.conf
fi
@@ -50,6 +50,9 @@ setup_url() {
if [ -n "${JIB_SERVER}" ]; then
jib_server="${JIB_SERVER}"
fi
+ if [ -n "${JIB_SERVER_MIRRORS}" ]; then
+ jib_server_mirrors="${JIB_SERVER_MIRRORS}"
+ fi
if [ -n "${JIB_REPOSITORY}" ]; then
jib_repository="${JIB_REPOSITORY}"
fi
@@ -70,8 +73,9 @@ setup_url() {
jib_url="${JIB_URL}"
data_string="${jib_url}"
else
- data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
- jib_url="${jib_server}/${data_string}"
+ jib_path="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
+ data_string="${jib_path}"
+ jib_url="${jib_server}/${jib_path}"
fi
}
@@ -104,7 +108,25 @@ install_jib() {
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
if [ ! -s "${installed_jib_script}.gz" ]; then
echo "Failed to download ${jib_url}"
- exit 1
+ if [ -n "${jib_path}" -a -n "${jib_server_mirrors}" ]; then
+ OLD_IFS="${IFS}"
+ IFS=" ,"
+ for mirror in ${jib_server_mirrors}; do
+ echo "Trying mirror ${mirror}"
+ jib_url="${mirror}/${jib_path}"
+ ${getcmd} ${jib_url} > "${installed_jib_script}.gz"
+ if [ -s "${installed_jib_script}.gz" ]; then
+ echo "Download from mirror successful"
+ break
+ else
+ echo "Failed to download ${jib_url}"
+ fi
+ done
+ IFS="${OLD_IFS}"
+ fi
+ if [ ! -s "${installed_jib_script}.gz" ]; then
+ exit 1
+ fi
fi
echo "Extracting JIB bootstrap script"
rm -f "${installed_jib_script}"
diff --git a/corba/.hgtags b/corba/.hgtags
index 9a465cddc83..9bd082d87fd 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -341,3 +341,4 @@ fd038e8a16eec80d0d6b337d74a582790ed4b3ee jdk-9+95
feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
10a482b863582376d4ca229090334b23b05159fc jdk-9+97
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
+180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index bd53ef2dfeb..ac6cea4d970 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -501,3 +501,4 @@ a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
+f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index bf7e74afb9c..a88e7f5e4e5 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -341,3 +341,4 @@ c8d0845877a811ab4350935892f826929359a3ff jdk-9+95
1f3182529f2c474e5506955ccb3820cfa5822265 jdk-9+96
9c107c050335d7ee63b2a8b38ca5d498f19713a2 jdk-9+97
52b01339235f24c93b679bd6b8fb36a1072ad0ac jdk-9+98
+52774b544850c791f1d1c67db2601b33739b18c9 jdk-9+99
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index c68a42d66d3..26b9274c712 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -344,3 +344,4 @@ e8d15c61400c1682a7873e053d7b39efde0b79be jdk9-b94
b55cebc47555293cf9c2aefb3bf63c56e847ab19 jdk-9+96
7293db4716ee25b814e14f738b9acfb85700e3fa jdk-9+97
67c84077edc3db6b24998b35970b37c01aae985e jdk-9+98
+97b31ca0dd77483cf20ff99a033a455673639578 jdk-9+99
diff --git a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java
index 897bbd325d8..4c6d00e50c4 100644
--- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java
+++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/adapters/XmlAdapter.java
@@ -31,10 +31,10 @@ package javax.xml.bind.annotation.adapters;
*
Usage:
*
*
- * Some Java types do not map naturally to a XML representation, for
+ * Some Java types do not map naturally to an XML representation, for
* example {@code HashMap} or other non JavaBean classes. Conversely,
- * a XML repsentation may map to a Java type but an application may
- * choose to accesss the XML representation using another Java
+ * an XML representation may map to a Java type but an application may
+ * choose to access the XML representation using another Java
* type. For example, the schema to Java binding rules bind
* xs:DateTime by default to XmlGregorianCalendar. But an application
* may desire to bind xs:DateTime to a custom type,
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 3058a7c90da..2af851e8faa 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -341,3 +341,4 @@ b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96
fdd84b2265ddce7f50e084b7c8635189bba6f012 jdk-9+97
f86ee68d1107dad41a27efc34306e0e56244a12e jdk-9+98
+e1a789be1535741274c9779f4d4ca3495196b5c3 jdk-9+99
diff --git a/jdk/make/launcher/Launcher-jdk.accessibility.gmk b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
index e2d25f989b9..e954e550f30 100644
--- a/jdk/make/launcher/Launcher-jdk.accessibility.gmk
+++ b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
@@ -73,8 +73,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \
SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
- CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
- LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib User32.lib, \
+ CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
+ LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
+ LIBS := advapi32.lib user32.lib, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
PROGRAM := jaccessinspector$1, \
@@ -100,8 +101,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
$$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \
SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \
$(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
- CFLAGS :== $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
- LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib Comctl32.lib Gdi32.lib User32.lib, \
+ CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
+ LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
+ LIBS := advapi32.lib comctl32.lib gdi32.lib user32.lib, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
PROGRAM := jaccesswalker$1, \
diff --git a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
index 1528b9e16b8..d9ae5ebe334 100644
--- a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
@@ -29,7 +29,6 @@ import java.io.IOException;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.util.*;
-import sun.misc.*;
/**
* An implementation of Selector for Linux 2.6+ kernels that uses
@@ -50,7 +49,7 @@ class EPollSelectorImpl
private Map fdToKey;
// True if this Selector has been closed
- private volatile boolean closed = false;
+ private volatile boolean closed;
// Lock for interrupt triggering and clearing
private final Object interruptLock = new Object();
diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
index 02af6a539d6..47dbc156250 100644
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
@@ -322,19 +322,6 @@ class LinuxWatchService
bytesRead = 0;
}
- // process any pending requests
- if ((nReady > 1) || (nReady == 1 && bytesRead == 0)) {
- try {
- read(socketpair[0], address, BUFFER_SIZE);
- boolean shutdown = processRequests();
- if (shutdown)
- break;
- } catch (UnixException x) {
- if (x.errno() != UnixConstants.EAGAIN)
- throw x;
- }
- }
-
// iterate over buffer to decode events
int offset = 0;
while (offset < bytesRead) {
@@ -369,6 +356,19 @@ class LinuxWatchService
offset += (SIZEOF_INOTIFY_EVENT + len);
}
+
+ // process any pending requests
+ if ((nReady > 1) || (nReady == 1 && bytesRead == 0)) {
+ try {
+ read(socketpair[0], address, BUFFER_SIZE);
+ boolean shutdown = processRequests();
+ if (shutdown)
+ break;
+ } catch (UnixException x) {
+ if (x.errno() != UnixConstants.EAGAIN)
+ throw x;
+ }
+ }
}
} catch (UnixException x) {
x.printStackTrace();
diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
index b2352b48603..089a662dce5 100644
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
@@ -93,7 +93,7 @@ public final class SunJCE extends Provider {
// Instance of this provider, so we don't have to call the provider list
// to find ourselves or run the risk of not being in the list.
- private static volatile SunJCE instance = null;
+ private static volatile SunJCE instance;
// lazy initialize SecureRandom to avoid potential recursion if Sun
// provider has not been installed yet
diff --git a/jdk/src/java.base/share/classes/java/io/File.java b/jdk/src/java.base/share/classes/java/io/File.java
index 6137d0acd29..089171bab9e 100644
--- a/jdk/src/java.base/share/classes/java/io/File.java
+++ b/jdk/src/java.base/share/classes/java/io/File.java
@@ -420,11 +420,11 @@ public class File
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
throw new IllegalArgumentException("URI scheme is not \"file\"");
- if (uri.getAuthority() != null)
+ if (uri.getRawAuthority() != null)
throw new IllegalArgumentException("URI has an authority component");
- if (uri.getFragment() != null)
+ if (uri.getRawFragment() != null)
throw new IllegalArgumentException("URI has a fragment component");
- if (uri.getQuery() != null)
+ if (uri.getRawQuery() != null)
throw new IllegalArgumentException("URI has a query component");
String p = uri.getPath();
if (p.equals(""))
diff --git a/jdk/src/java.base/share/classes/java/io/PipedInputStream.java b/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
index 7f27fde0893..b55c1b08b75 100644
--- a/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
+++ b/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
@@ -48,9 +48,9 @@ package java.io;
* @since 1.0
*/
public class PipedInputStream extends InputStream {
- boolean closedByWriter = false;
- volatile boolean closedByReader = false;
- boolean connected = false;
+ boolean closedByWriter;
+ volatile boolean closedByReader;
+ boolean connected;
/* REMIND: identification of the read and write sides needs to be
more sophisticated. Either using thread groups (but what about
diff --git a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
index 975c806bc81..619b7de278a 100644
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
@@ -25,7 +25,7 @@
package java.lang;
-import sun.misc.FloatingDecimal;
+import jdk.internal.math.FloatingDecimal;
import java.util.Arrays;
import java.util.Spliterator;
import java.util.stream.IntStream;
diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java
index 77913c3187d..013b5843a1e 100644
--- a/jdk/src/java.base/share/classes/java/lang/Class.java
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java
@@ -2518,7 +2518,7 @@ public final class Class implements java.io.Serializable,
// Incremented by the VM on each call to JVM TI RedefineClasses()
// that redefines this class or a superclass.
- private transient volatile int classRedefinedCount = 0;
+ private transient volatile int classRedefinedCount;
// Lazily create and cache ReflectionData
private ReflectionData reflectionData() {
@@ -3331,7 +3331,8 @@ public final class Class implements java.io.Serializable,
* uncloned, cached, and shared by all callers.
*/
T[] getEnumConstantsShared() {
- if (enumConstants == null) {
+ T[] constants = enumConstants;
+ if (constants == null) {
if (!isEnum()) return null;
try {
final Method values = getMethod("values");
@@ -3344,16 +3345,16 @@ public final class Class implements java.io.Serializable,
});
@SuppressWarnings("unchecked")
T[] temporaryConstants = (T[])values.invoke(null);
- enumConstants = temporaryConstants;
+ enumConstants = constants = temporaryConstants;
}
// These can happen when users concoct enum-like classes
// that don't comply with the enum spec.
catch (InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex) { return null; }
}
- return enumConstants;
+ return constants;
}
- private transient volatile T[] enumConstants = null;
+ private transient volatile T[] enumConstants;
/**
* Returns a map from simple name to enum constant. This package-private
@@ -3363,19 +3364,21 @@ public final class Class implements java.io.Serializable,
* created lazily on first use. Typically it won't ever get created.
*/
Map enumConstantDirectory() {
- if (enumConstantDirectory == null) {
+ Map directory = enumConstantDirectory;
+ if (directory == null) {
T[] universe = getEnumConstantsShared();
if (universe == null)
throw new IllegalArgumentException(
getName() + " is not an enum type");
- Map m = new HashMap<>(2 * universe.length);
- for (T constant : universe)
- m.put(((Enum>)constant).name(), constant);
- enumConstantDirectory = m;
+ directory = new HashMap<>(2 * universe.length);
+ for (T constant : universe) {
+ directory.put(((Enum>)constant).name(), constant);
+ }
+ enumConstantDirectory = directory;
}
- return enumConstantDirectory;
+ return directory;
}
- private transient volatile Map enumConstantDirectory = null;
+ private transient volatile Map enumConstantDirectory;
/**
* Casts an object to the class or interface represented
diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
index a3009062c2d..76cdd25dcd7 100644
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -45,11 +45,11 @@ import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.reflect.CallerSensitive;
@@ -2206,3 +2206,36 @@ class SystemClassLoaderAction
return sys;
}
}
+
+/*
+ * A utility class that will enumerate over an array of enumerations.
+ */
+final class CompoundEnumeration implements Enumeration {
+ private final Enumeration[] enums;
+ private int index;
+
+ public CompoundEnumeration(Enumeration[] enums) {
+ this.enums = enums;
+ }
+
+ private boolean next() {
+ while (index < enums.length) {
+ if (enums[index] != null && enums[index].hasMoreElements()) {
+ return true;
+ }
+ index++;
+ }
+ return false;
+ }
+
+ public boolean hasMoreElements() {
+ return next();
+ }
+
+ public E nextElement() {
+ if (!next()) {
+ throw new NoSuchElementException();
+ }
+ return enums[index].nextElement();
+ }
+}
diff --git a/jdk/src/java.base/share/classes/java/lang/Double.java b/jdk/src/java.base/share/classes/java/lang/Double.java
index 88201873c36..f1389ebe0f8 100644
--- a/jdk/src/java.base/share/classes/java/lang/Double.java
+++ b/jdk/src/java.base/share/classes/java/lang/Double.java
@@ -25,8 +25,8 @@
package java.lang;
-import sun.misc.FloatingDecimal;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatingDecimal;
+import jdk.internal.math.DoubleConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
diff --git a/jdk/src/java.base/share/classes/java/lang/Float.java b/jdk/src/java.base/share/classes/java/lang/Float.java
index f9d3f9ef325..09eb63527ab 100644
--- a/jdk/src/java.base/share/classes/java/lang/Float.java
+++ b/jdk/src/java.base/share/classes/java/lang/Float.java
@@ -25,9 +25,9 @@
package java.lang;
-import sun.misc.FloatingDecimal;
-import sun.misc.FloatConsts;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatingDecimal;
+import jdk.internal.math.FloatConsts;
+import jdk.internal.math.DoubleConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
diff --git a/jdk/src/java.base/share/classes/java/lang/Math.java b/jdk/src/java.base/share/classes/java/lang/Math.java
index 1cd32bd3839..ddb953225a8 100644
--- a/jdk/src/java.base/share/classes/java/lang/Math.java
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java
@@ -26,8 +26,8 @@
package java.lang;
import java.util.Random;
-import sun.misc.FloatConsts;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatConsts;
+import jdk.internal.math.DoubleConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
diff --git a/jdk/src/java.base/share/classes/java/lang/StrictMath.java b/jdk/src/java.base/share/classes/java/lang/StrictMath.java
index 68bba059786..0c82f6afbf5 100644
--- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java
+++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java
@@ -26,7 +26,7 @@
package java.lang;
import java.util.Random;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.DoubleConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java
index cf44391082c..ea3ad405cfc 100644
--- a/jdk/src/java.base/share/classes/java/lang/System.java
+++ b/jdk/src/java.base/share/classes/java/lang/System.java
@@ -132,7 +132,7 @@ public final class System {
/* The security manager for the system.
*/
- private static volatile SecurityManager security = null;
+ private static volatile SecurityManager security;
/**
* Reassigns the "standard" input stream.
@@ -206,7 +206,7 @@ public final class System {
setErr0(err);
}
- private static volatile Console cons = null;
+ private static volatile Console cons;
/**
* Returns the unique {@link java.io.Console Console} object associated
* with the current Java virtual machine, if any.
@@ -216,12 +216,13 @@ public final class System {
* @since 1.6
*/
public static Console console() {
- if (cons == null) {
+ Console c = cons;
+ if (c == null) {
synchronized (System.class) {
- cons = SharedSecrets.getJavaIOAccess().console();
+ cons = c = SharedSecrets.getJavaIOAccess().console();
}
}
- return cons;
+ return c;
}
/**
diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java
index e40aa6f0d51..56935eabd34 100644
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java
@@ -207,12 +207,10 @@ class Thread implements Runnable {
/* For generating thread ID */
private static long threadSeqNumber;
- /* Java thread status for tools,
- * initialized to indicate thread 'not yet started'
+ /*
+ * Java thread status for tools, default indicates thread 'not yet started'
*/
-
- private volatile int threadStatus = 0;
-
+ private volatile int threadStatus;
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
diff --git a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
index d23491906c1..dcd50ae8575 100644
--- a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
+++ b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
@@ -53,7 +53,7 @@ public class ReferenceQueue {
private static class Lock { };
private Lock lock = new Lock();
- private volatile Reference extends T> head = null;
+ private volatile Reference extends T> head;
private long queueLength = 0;
boolean enqueue(Reference extends T> r) { /* Called only by Reference class */
diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
index 5c178503fa8..005f0ddf5f3 100644
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
@@ -205,7 +205,7 @@ public final class Parameter implements AnnotatedElement {
return tmp;
}
- private transient volatile Type parameterTypeCache = null;
+ private transient volatile Type parameterTypeCache;
/**
* Returns a {@code Class} object that identifies the
@@ -237,7 +237,7 @@ public final class Parameter implements AnnotatedElement {
return executable.getAnnotatedParameterTypes()[index];
}
- private transient volatile Class> parameterClassCache = null;
+ private transient volatile Class> parameterClassCache;
/**
* Returns {@code true} if this parameter is implicitly declared
diff --git a/jdk/src/java.base/share/classes/java/math/BigInteger.java b/jdk/src/java.base/share/classes/java/math/BigInteger.java
index 1c44659daf4..c77731b2418 100644
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java
@@ -38,8 +38,8 @@ import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
-import sun.misc.DoubleConsts;
-import sun.misc.FloatConsts;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FloatConsts;
import jdk.internal.HotSpotIntrinsicCandidate;
/**
diff --git a/jdk/src/java.base/share/classes/java/net/URI.java b/jdk/src/java.base/share/classes/java/net/URI.java
index 134a8b4380f..e896568c7a1 100644
--- a/jdk/src/java.base/share/classes/java/net/URI.java
+++ b/jdk/src/java.base/share/classes/java/net/URI.java
@@ -33,7 +33,6 @@ import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
@@ -490,17 +489,17 @@ public final class URI
private transient String path; // null ==> opaque
private transient String query;
- // The remaining fields may be computed on demand
+ // The remaining fields may be computed on demand, which is safe even in
+ // the face of multiple threads racing to initialize them
+ private transient String schemeSpecificPart;
+ private transient int hash; // Zero ==> undefined
- private transient volatile String schemeSpecificPart;
- private transient volatile int hash; // Zero ==> undefined
-
- private transient volatile String decodedUserInfo = null;
- private transient volatile String decodedAuthority = null;
- private transient volatile String decodedPath = null;
- private transient volatile String decodedQuery = null;
- private transient volatile String decodedFragment = null;
- private transient volatile String decodedSchemeSpecificPart = null;
+ private transient String decodedUserInfo;
+ private transient String decodedAuthority;
+ private transient String decodedPath;
+ private transient String decodedQuery;
+ private transient String decodedFragment;
+ private transient String decodedSchemeSpecificPart;
/**
* The string form of this URI.
@@ -911,8 +910,7 @@ public final class URI
// either more fields or a more-obscure representation.
if ((host != null) || (authority == null))
return this;
- defineString();
- new Parser(string).parse(true);
+ new Parser(toString()).parse(true);
return this;
}
@@ -1144,8 +1142,17 @@ public final class URI
* (never {@code null})
*/
public String getRawSchemeSpecificPart() {
- defineSchemeSpecificPart();
- return schemeSpecificPart;
+ String part = schemeSpecificPart;
+ if (part != null) {
+ return part;
+ }
+ StringBuilder sb = new StringBuilder();
+ appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
+ host, port, getPath(), getQuery());
+ if (sb.length() == 0) {
+ return null;
+ }
+ return schemeSpecificPart = sb.toString();
}
/**
@@ -1160,9 +1167,11 @@ public final class URI
* (never {@code null})
*/
public String getSchemeSpecificPart() {
- if (decodedSchemeSpecificPart == null)
- decodedSchemeSpecificPart = decode(getRawSchemeSpecificPart());
- return decodedSchemeSpecificPart;
+ String part = decodedSchemeSpecificPart;
+ if (part == null) {
+ decodedSchemeSpecificPart = part = decode(getRawSchemeSpecificPart());
+ }
+ return part;
}
/**
@@ -1193,9 +1202,11 @@ public final class URI
* or {@code null} if the authority is undefined
*/
public String getAuthority() {
- if (decodedAuthority == null)
- decodedAuthority = decode(authority);
- return decodedAuthority;
+ String auth = decodedAuthority;
+ if ((auth == null) && (authority != null)) {
+ decodedAuthority = auth = decode(authority);
+ }
+ return auth;
}
/**
@@ -1223,9 +1234,11 @@ public final class URI
* or {@code null} if the user information is undefined
*/
public String getUserInfo() {
- if ((decodedUserInfo == null) && (userInfo != null))
- decodedUserInfo = decode(userInfo);
- return decodedUserInfo;
+ String user = decodedUserInfo;
+ if ((user == null) && (userInfo != null)) {
+ decodedUserInfo = user = decode(userInfo);
+ }
+ return user;
}
/**
@@ -1307,9 +1320,11 @@ public final class URI
* or {@code null} if the path is undefined
*/
public String getPath() {
- if ((decodedPath == null) && (path != null))
- decodedPath = decode(path);
- return decodedPath;
+ String decoded = decodedPath;
+ if ((decoded == null) && (path != null)) {
+ decodedPath = decoded = decode(path);
+ }
+ return decoded;
}
/**
@@ -1336,9 +1351,11 @@ public final class URI
* or {@code null} if the query is undefined
*/
public String getQuery() {
- if ((decodedQuery == null) && (query != null))
- decodedQuery = decode(query, false);
- return decodedQuery;
+ String decoded = decodedQuery;
+ if ((decoded == null) && (query != null)) {
+ decodedQuery = decoded = decode(query, false);
+ }
+ return decoded;
}
/**
@@ -1365,9 +1382,11 @@ public final class URI
* or {@code null} if the fragment is undefined
*/
public String getFragment() {
- if ((decodedFragment == null) && (fragment != null))
- decodedFragment = decode(fragment, false);
- return decodedFragment;
+ String decoded = decodedFragment;
+ if ((decoded == null) && (fragment != null)) {
+ decodedFragment = decoded = decode(fragment, false);
+ }
+ return decoded;
}
@@ -1453,24 +1472,27 @@ public final class URI
* @return A hash-code value for this URI
*/
public int hashCode() {
- if (hash != 0)
- return hash;
- int h = hashIgnoringCase(0, scheme);
- h = hash(h, fragment);
- if (isOpaque()) {
- h = hash(h, schemeSpecificPart);
- } else {
- h = hash(h, path);
- h = hash(h, query);
- if (host != null) {
- h = hash(h, userInfo);
- h = hashIgnoringCase(h, host);
- h += 1949 * port;
+ int h = hash;
+ if (h == 0) {
+ h = hashIgnoringCase(0, scheme);
+ h = hash(h, fragment);
+ if (isOpaque()) {
+ h = hash(h, schemeSpecificPart);
} else {
- h = hash(h, authority);
+ h = hash(h, path);
+ h = hash(h, query);
+ if (host != null) {
+ h = hash(h, userInfo);
+ h = hashIgnoringCase(h, host);
+ h += 1949 * port;
+ } else {
+ h = hash(h, authority);
+ }
+ }
+ if (h != 0) {
+ hash = h;
}
}
- hash = h;
return h;
}
@@ -1600,8 +1622,59 @@ public final class URI
* @return The string form of this URI
*/
public String toString() {
- defineString();
- return string;
+ String s = string;
+ if (s == null) {
+ s = defineString();
+ }
+ return s;
+ }
+
+ private String defineString() {
+ String s = string;
+ if (s != null) {
+ return s;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ if (scheme != null) {
+ sb.append(scheme);
+ sb.append(':');
+ }
+ if (isOpaque()) {
+ sb.append(schemeSpecificPart);
+ } else {
+ if (host != null) {
+ sb.append("//");
+ if (userInfo != null) {
+ sb.append(userInfo);
+ sb.append('@');
+ }
+ boolean needBrackets = ((host.indexOf(':') >= 0)
+ && !host.startsWith("[")
+ && !host.endsWith("]"));
+ if (needBrackets) sb.append('[');
+ sb.append(host);
+ if (needBrackets) sb.append(']');
+ if (port != -1) {
+ sb.append(':');
+ sb.append(port);
+ }
+ } else if (authority != null) {
+ sb.append("//");
+ sb.append(authority);
+ }
+ if (path != null)
+ sb.append(path);
+ if (query != null) {
+ sb.append('?');
+ sb.append(query);
+ }
+ }
+ if (fragment != null) {
+ sb.append('#');
+ sb.append(fragment);
+ }
+ return string = sb.toString();
}
/**
@@ -1618,8 +1691,7 @@ public final class URI
* charset
*/
public String toASCIIString() {
- defineString();
- return encode(string);
+ return encode(toString());
}
@@ -1825,7 +1897,7 @@ public final class URI
}
}
- private void appendAuthority(StringBuffer sb,
+ private void appendAuthority(StringBuilder sb,
String authority,
String userInfo,
String host,
@@ -1875,7 +1947,7 @@ public final class URI
}
}
- private void appendSchemeSpecificPart(StringBuffer sb,
+ private void appendSchemeSpecificPart(StringBuilder sb,
String opaquePart,
String authority,
String userInfo,
@@ -1916,7 +1988,7 @@ public final class URI
}
}
- private void appendFragment(StringBuffer sb, String fragment) {
+ private void appendFragment(StringBuilder sb, String fragment) {
if (fragment != null) {
sb.append('#');
sb.append(quote(fragment, L_URIC, H_URIC));
@@ -1933,7 +2005,7 @@ public final class URI
String query,
String fragment)
{
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
if (scheme != null) {
sb.append(scheme);
sb.append(':');
@@ -1945,61 +2017,6 @@ public final class URI
return sb.toString();
}
- private void defineSchemeSpecificPart() {
- if (schemeSpecificPart != null) return;
- StringBuffer sb = new StringBuffer();
- appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
- host, port, getPath(), getQuery());
- if (sb.length() == 0) return;
- schemeSpecificPart = sb.toString();
- }
-
- private void defineString() {
- if (string != null) return;
-
- StringBuilder sb = new StringBuilder();
- if (scheme != null) {
- sb.append(scheme);
- sb.append(':');
- }
- if (isOpaque()) {
- sb.append(schemeSpecificPart);
- } else {
- if (host != null) {
- sb.append("//");
- if (userInfo != null) {
- sb.append(userInfo);
- sb.append('@');
- }
- boolean needBrackets = ((host.indexOf(':') >= 0)
- && !host.startsWith("[")
- && !host.endsWith("]"));
- if (needBrackets) sb.append('[');
- sb.append(host);
- if (needBrackets) sb.append(']');
- if (port != -1) {
- sb.append(':');
- sb.append(port);
- }
- } else if (authority != null) {
- sb.append("//");
- sb.append(authority);
- }
- if (path != null)
- sb.append(path);
- if (query != null) {
- sb.append('?');
- sb.append(query);
- }
- }
- if (fragment != null) {
- sb.append('#');
- sb.append(fragment);
- }
- string = sb.toString();
- }
-
-
// -- Normalization, resolution, and relativization --
// RFC2396 5.2 (6)
@@ -2650,13 +2667,13 @@ public final class URI
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
- private static void appendEscape(StringBuffer sb, byte b) {
+ private static void appendEscape(StringBuilder sb, byte b) {
sb.append('%');
sb.append(hexDigits[(b >> 4) & 0x0f]);
sb.append(hexDigits[(b >> 0) & 0x0f]);
}
- private static void appendEncoded(StringBuffer sb, char c) {
+ private static void appendEncoded(StringBuilder sb, char c) {
ByteBuffer bb = null;
try {
bb = ThreadLocalCoders.encoderFor("UTF-8")
@@ -2677,15 +2694,14 @@ public final class URI
// by the given mask pair
//
private static String quote(String s, long lowMask, long highMask) {
- int n = s.length();
- StringBuffer sb = null;
+ StringBuilder sb = null;
boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c < '\u0080') {
if (!match(c, lowMask, highMask)) {
if (sb == null) {
- sb = new StringBuffer();
+ sb = new StringBuilder();
sb.append(s, 0, i);
}
appendEscape(sb, (byte)c);
@@ -2697,7 +2713,7 @@ public final class URI
&& (Character.isSpaceChar(c)
|| Character.isISOControl(c))) {
if (sb == null) {
- sb = new StringBuffer();
+ sb = new StringBuilder();
sb.append(s, 0, i);
}
appendEncoded(sb, c);
@@ -2734,7 +2750,7 @@ public final class URI
assert false;
}
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
while (bb.hasRemaining()) {
int b = bb.get() & 0xff;
if (b >= 0x80)
@@ -2865,12 +2881,6 @@ public final class URI
fail("Expected " + expected, p);
}
- private void failExpecting(String expected, String prior, int p)
- throws URISyntaxException
- {
- fail("Expected " + expected + " following " + prior, p);
- }
-
// -- Simple access to the input string --
diff --git a/jdk/src/java.base/share/classes/java/net/URL.java b/jdk/src/java.base/share/classes/java/net/URL.java
index 1a32a236ba0..73e488831a5 100644
--- a/jdk/src/java.base/share/classes/java/net/URL.java
+++ b/jdk/src/java.base/share/classes/java/net/URL.java
@@ -310,7 +310,8 @@ public final class URL implements java.io.Serializable {
* @param host the name of the host.
* @param port the port number on the host.
* @param file the file on the host
- * @exception MalformedURLException if an unknown protocol is specified.
+ * @exception MalformedURLException if an unknown protocol or the port
+ * is a negative number other than -1
* @see java.lang.System#getProperty(java.lang.String)
* @see java.net.URL#setURLStreamHandlerFactory(
* java.net.URLStreamHandlerFactory)
@@ -329,9 +330,9 @@ public final class URL implements java.io.Serializable {
* name, {@code host} name, and {@code file} name. The
* default port for the specified protocol is used.
*
- * This method is equivalent to calling the four-argument
- * constructor with the arguments being {@code protocol},
- * {@code host}, {@code -1}, and {@code file}.
+ * This constructor is equivalent to the four-argument
+ * constructor with the only difference of using the
+ * default port for the specified protocol.
*
* No validation of the inputs is performed by this constructor.
*
@@ -372,7 +373,8 @@ public final class URL implements java.io.Serializable {
* @param port the port number on the host.
* @param file the file on the host
* @param handler the stream handler for the URL.
- * @exception MalformedURLException if an unknown protocol is specified.
+ * @exception MalformedURLException if an unknown protocol or the port
+ is a negative number other than -1
* @exception SecurityException
* if a security manager exists and its
* {@code checkPermission} method doesn't allow
@@ -446,7 +448,9 @@ public final class URL implements java.io.Serializable {
*
* @param spec the {@code String} to parse as a URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or {@code spec} is {@code null}.
+ * unknown protocol is found, or {@code spec} is {@code null},
+ * or the parsed URL fails to comply with the specific syntax
+ * of the associated protocol.
* @see java.net.URL#URL(java.net.URL, java.lang.String)
*/
public URL(String spec) throws MalformedURLException {
@@ -493,7 +497,9 @@ public final class URL implements java.io.Serializable {
* @param context the context in which to parse the specification.
* @param spec the {@code String} to parse as a URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or {@code spec} is {@code null}.
+ * unknown protocol is found, or {@code spec} is {@code null},
+ * or the parsed URL fails to comply with the specific syntax
+ * of the associated protocol.
* @see java.net.URL#URL(java.lang.String, java.lang.String,
* int, java.lang.String)
* @see java.net.URLStreamHandler
@@ -513,7 +519,9 @@ public final class URL implements java.io.Serializable {
* @param spec the {@code String} to parse as a URL.
* @param handler the stream handler for the URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or {@code spec} is {@code null}.
+ * unknown protocol is found, or {@code spec} is {@code null},
+ * or the parsed URL fails to comply with the specific syntax
+ * of the associated protocol.
* @exception SecurityException
* if a security manager exists and its
* {@code checkPermission} method doesn't allow
diff --git a/jdk/src/java.base/share/classes/java/net/URLConnection.java b/jdk/src/java.base/share/classes/java/net/URLConnection.java
index 544107828b9..0fe18279b1b 100644
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, 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
@@ -1550,7 +1550,7 @@ public abstract class URLConnection {
}
if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
- if (c4 == 0xE0) {
+ if (c4 == 0xE0 || c4 == 0xEE) {
return "image/jpeg";
}
@@ -1565,10 +1565,6 @@ public abstract class URLConnection {
c11 == 0)) {
return "image/jpeg";
}
-
- if (c4 == 0xEE) {
- return "image/jpg";
- }
}
if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
diff --git a/jdk/src/java.base/share/classes/java/nio/Bits.java b/jdk/src/java.base/share/classes/java/nio/Bits.java
index 526c71d3f8b..724fb0c01f5 100644
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java
@@ -25,9 +25,7 @@
package java.nio;
-import java.security.AccessController;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.LongAdder;
import jdk.internal.misc.JavaNioAccess;
import jdk.internal.misc.JavaLangRefAccess;
@@ -603,7 +601,8 @@ class Bits { // package-private
private static final AtomicLong reservedMemory = new AtomicLong();
private static final AtomicLong totalCapacity = new AtomicLong();
private static final AtomicLong count = new AtomicLong();
- private static volatile boolean memoryLimitSet = false;
+ private static volatile boolean memoryLimitSet;
+
// max. number of sleeps during try-reserving with exponentially
// increasing delay before throwing OutOfMemoryError:
// 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
diff --git a/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java b/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
index 86c133d192f..bd7c74de52a 100644
--- a/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
+++ b/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
@@ -26,8 +26,6 @@
package java.nio.channels;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.io.IOException;
-
/**
* A token representing the registration of a {@link SelectableChannel} with a
@@ -363,7 +361,7 @@ public abstract class SelectionKey {
// -- Attachments --
- private volatile Object attachment = null;
+ private volatile Object attachment;
private static final AtomicReferenceFieldUpdater
attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
diff --git a/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java b/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
index dcf54cb7d0c..cc82cb7a83c 100644
--- a/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
+++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -29,11 +29,7 @@
package java.nio.channels.spi;
import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
import java.nio.channels.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import jdk.internal.misc.SharedSecrets;
import sun.nio.ch.Interruptible;
@@ -90,7 +86,7 @@ public abstract class AbstractInterruptibleChannel
{
private final Object closeLock = new Object();
- private volatile boolean open = true;
+ private volatile boolean closed;
/**
* Initializes a new instance of this class.
@@ -110,9 +106,9 @@ public abstract class AbstractInterruptibleChannel
*/
public final void close() throws IOException {
synchronized (closeLock) {
- if (!open)
+ if (closed)
return;
- open = false;
+ closed = true;
implCloseChannel();
}
}
@@ -136,7 +132,7 @@ public abstract class AbstractInterruptibleChannel
protected abstract void implCloseChannel() throws IOException;
public final boolean isOpen() {
- return open;
+ return !closed;
}
@@ -158,9 +154,9 @@ public abstract class AbstractInterruptibleChannel
interruptor = new Interruptible() {
public void interrupt(Thread target) {
synchronized (closeLock) {
- if (!open)
+ if (closed)
return;
- open = false;
+ closed = true;
interrupted = target;
try {
AbstractInterruptibleChannel.this.implCloseChannel();
@@ -202,7 +198,7 @@ public abstract class AbstractInterruptibleChannel
this.interrupted = null;
throw new ClosedByInterruptException();
}
- if (!completed && !open)
+ if (!completed && closed)
throw new AsynchronousCloseException();
}
diff --git a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
index 498ed365213..d48f5a972db 100644
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
@@ -276,7 +276,7 @@ public abstract class Charset
/* -- Static methods -- */
- private static volatile String bugLevel = null;
+ private static volatile String bugLevel;
static boolean atBugLevel(String bl) { // package-private
String level = bugLevel;
@@ -324,8 +324,8 @@ public abstract class Charset
// Cache of the most-recently-returned charsets,
// along with the names that were used to find them
//
- private static volatile Object[] cache1 = null; // "Level 1" cache
- private static volatile Object[] cache2 = null; // "Level 2" cache
+ private static volatile Object[] cache1; // "Level 1" cache
+ private static volatile Object[] cache2; // "Level 2" cache
private static void cache(String charsetName, Charset cs) {
cache2 = cache1;
diff --git a/jdk/src/java.base/share/classes/java/security/SecureRandom.java b/jdk/src/java.base/share/classes/java/security/SecureRandom.java
index a2a246f4a14..543b7abd98f 100644
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java
@@ -124,7 +124,7 @@ public class SecureRandom extends java.util.Random {
private String algorithm;
// Seed Generator
- private static volatile SecureRandom seedGenerator = null;
+ private static volatile SecureRandom seedGenerator;
/**
* Constructs a secure random number generator (RNG) implementing the
@@ -522,10 +522,12 @@ public class SecureRandom extends java.util.Random {
* @see #setSeed
*/
public static byte[] getSeed(int numBytes) {
- if (seedGenerator == null) {
- seedGenerator = new SecureRandom();
+ SecureRandom seedGen = seedGenerator;
+ if (seedGen == null) {
+ seedGen = new SecureRandom();
+ seedGenerator = seedGen;
}
- return seedGenerator.generateSeed(numBytes);
+ return seedGen.generateSeed(numBytes);
}
/**
diff --git a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
index c1f951d5bf8..955415af8b6 100644
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
+++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
@@ -630,7 +630,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
hashCode = 11 * hashCode + Arrays.hashCode(ampms);
hashCode = 11 * hashCode + Arrays.deepHashCode(getZoneStringsWrapper());
hashCode = 11 * hashCode + Objects.hashCode(localPatternChars);
- cachedHashCode = hashCode;
+ if (hashCode != 0) {
+ cachedHashCode = hashCode;
+ }
}
return hashCode;
@@ -670,12 +672,12 @@ public class DateFormatSymbols implements Serializable, Cloneable {
private static final ConcurrentMap> cachedInstances
= new ConcurrentHashMap<>(3);
- private transient int lastZoneIndex = 0;
+ private transient int lastZoneIndex;
/**
* Cached hash code
*/
- transient volatile int cachedHashCode = 0;
+ transient volatile int cachedHashCode;
private void initializeData(Locale desiredLocale) {
locale = desiredLocale;
diff --git a/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
index 6727197ef81..cf7e7e5ffc7 100644
--- a/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
+++ b/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
@@ -42,14 +42,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.text.spi.DecimalFormatSymbolsProvider;
-import java.util.ArrayList;
import java.util.Currency;
-import java.util.List;
import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.LocaleServiceProviderPool;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
@@ -875,7 +869,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
// currency; only the ISO code is serialized.
private transient Currency currency;
- private transient volatile boolean currencyInitialized = false;
+ private transient volatile boolean currencyInitialized;
// Proclaim JDK 1.1 FCS compatibility
static final long serialVersionUID = 5772796243397350300L;
diff --git a/jdk/src/java.base/share/classes/java/text/DigitList.java b/jdk/src/java.base/share/classes/java/text/DigitList.java
index 0b73543a9d4..708e3e64575 100644
--- a/jdk/src/java.base/share/classes/java/text/DigitList.java
+++ b/jdk/src/java.base/share/classes/java/text/DigitList.java
@@ -41,7 +41,7 @@ package java.text;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
-import sun.misc.FloatingDecimal;
+import jdk.internal.math.FloatingDecimal;
/**
* Digit List. Private to DecimalFormat.
diff --git a/jdk/src/java.base/share/classes/java/time/LocalDate.java b/jdk/src/java.base/share/classes/java/time/LocalDate.java
index 0d47deeac3a..0c6c755b813 100644
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java
@@ -147,6 +147,10 @@ public final class LocalDate
* This could be used by an application as a "far future" date.
*/
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
+ /**
+ * The epoch year {@code LocalDate}, '1970-01-01'.
+ */
+ public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
/**
* Serialization version.
@@ -1864,6 +1868,29 @@ public final class LocalDate
return total - DAYS_0000_TO_1970;
}
+ /**
+ * Converts this {@code LocalDate} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ *
+ * This combines this local date with the specified time and
+ * offset to calculate the epoch-second value, which is the
+ * number of elapsed seconds from 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param time the local time, not null
+ * @param offset the zone offset, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalTime time, ZoneOffset offset) {
+ Objects.requireNonNull(time, "time");
+ Objects.requireNonNull(offset, "offset");
+ long secs = toEpochDay() * SECONDS_PER_DAY + time.toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this date to another date.
diff --git a/jdk/src/java.base/share/classes/java/time/LocalTime.java b/jdk/src/java.base/share/classes/java/time/LocalTime.java
index 6b41e8579ad..7cd4adf693f 100644
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java
@@ -1490,6 +1490,30 @@ public final class LocalTime
return total;
}
+ /**
+ * Converts this {@code LocalTime} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ *
+ * This combines this local time with the specified date and
+ * offset to calculate the epoch-second value, which is the
+ * number of elapsed seconds from 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param date the local date, not null
+ * @param offset the zone offset, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalDate date, ZoneOffset offset) {
+ Objects.requireNonNull(date, "date");
+ Objects.requireNonNull(offset, "offset");
+ long epochDay = date.toEpochDay();
+ long secs = epochDay * 86400 + toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this time to another time.
diff --git a/jdk/src/java.base/share/classes/java/time/OffsetTime.java b/jdk/src/java.base/share/classes/java/time/OffsetTime.java
index fca51fd8941..1df445da650 100644
--- a/jdk/src/java.base/share/classes/java/time/OffsetTime.java
+++ b/jdk/src/java.base/share/classes/java/time/OffsetTime.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
@@ -1232,6 +1232,28 @@ public final class OffsetTime
return nod - offsetNanos;
}
+ /**
+ * Converts this {@code OffsetTime} to the number of seconds since the epoch
+ * of 1970-01-01T00:00:00Z.
+ *
+ * This combines this offset time with the specified date to calculate the
+ * epoch-second value, which is the number of elapsed seconds from
+ * 1970-01-01T00:00:00Z.
+ * Instants on the time-line after the epoch are positive, earlier
+ * are negative.
+ *
+ * @param date the localdate, not null
+ * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+ * @since 9
+ */
+ public long toEpochSecond(LocalDate date) {
+ Objects.requireNonNull(date, "date");
+ long epochDay = date.toEpochDay();
+ long secs = epochDay * 86400 + time.toSecondOfDay();
+ secs -= offset.getTotalSeconds();
+ return secs;
+ }
+
//-----------------------------------------------------------------------
/**
* Compares this {@code OffsetTime} to another time.
diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java
index 32e17093c68..01498d340a5 100644
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java
@@ -80,6 +80,7 @@ import java.time.DateTimeException;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
+import java.time.chrono.ChronoLocalDateTime;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser;
@@ -473,6 +474,17 @@ import java.util.Set;
* day-of-week was valid for the date.
*
If an {@linkplain #parsedExcessDays() excess number of days}
* was parsed then it is added to the date if a date is available.
+ * If a second-based field is present, but {@code LocalTime} was not parsed,
+ * then the resolver ensures that milli, micro and nano second values are
+ * available to meet the contract of {@link ChronoField}.
+ * These will be set to zero if missing.
+ * If both date and time were parsed and either an offset or zone is present,
+ * the field {@link ChronoField#INSTANT_SECONDS} is created.
+ * If an offset was parsed then the offset will be combined with the
+ * {@code LocalDateTime} to form the instant, with any zone ignored.
+ * If a {@code ZoneId} was parsed without an offset then the zone will be
+ * combined with the {@code LocalDateTime} to form the instant using the rules
+ * of {@link ChronoLocalDateTime#atZone(ZoneId)}.
*
*
* @implSpec
diff --git a/jdk/src/java.base/share/classes/java/time/format/Parsed.java b/jdk/src/java.base/share/classes/java/time/format/Parsed.java
index 58cbfaffbef..a2a75fa4c5a 100644
--- a/jdk/src/java.base/share/classes/java/time/format/Parsed.java
+++ b/jdk/src/java.base/share/classes/java/time/format/Parsed.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
@@ -594,15 +594,16 @@ final class Parsed implements TemporalAccessor {
private void resolveInstant() {
// add instant seconds if we have date, time and zone
+ // Offset (if present) will be given priority over the zone.
if (date != null && time != null) {
- if (zone != null) {
- long instant = date.atTime(time).atZone(zone).getLong(ChronoField.INSTANT_SECONDS);
+ Long offsetSecs = fieldValues.get(OFFSET_SECONDS);
+ if (offsetSecs != null) {
+ ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
+ long instant = date.atTime(time).atZone(offset).toEpochSecond();
fieldValues.put(INSTANT_SECONDS, instant);
} else {
- Long offsetSecs = fieldValues.get(OFFSET_SECONDS);
- if (offsetSecs != null) {
- ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSecs.intValue());
- long instant = date.atTime(time).atZone(offset).getLong(ChronoField.INSTANT_SECONDS);
+ if (zone != null) {
+ long instant = date.atTime(time).atZone(zone).toEpochSecond();
fieldValues.put(INSTANT_SECONDS, instant);
}
}
diff --git a/jdk/src/java.base/share/classes/java/util/Formatter.java b/jdk/src/java.base/share/classes/java/util/Formatter.java
index 0a3b50b6a13..c771ac1ba0c 100644
--- a/jdk/src/java.base/share/classes/java/util/Formatter.java
+++ b/jdk/src/java.base/share/classes/java/util/Formatter.java
@@ -60,8 +60,8 @@ import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQueries;
import java.time.temporal.UnsupportedTemporalTypeException;
-import sun.misc.DoubleConsts;
-import sun.misc.FormattedFloatingDecimal;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FormattedFloatingDecimal;
/**
* An interpreter for printf-style format strings. This class provides support
diff --git a/jdk/src/java.base/share/classes/java/util/Locale.java b/jdk/src/java.base/share/classes/java/util/Locale.java
index d01891be0c5..25697ca0c9d 100644
--- a/jdk/src/java.base/share/classes/java/util/Locale.java
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java
@@ -62,7 +62,6 @@ import sun.util.locale.ParseStatus;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.LocaleResources;
import sun.util.locale.provider.LocaleServiceProviderPool;
-import sun.util.locale.provider.ResourceBundleBasedAdapter;
/**
* A Locale object represents a specific geographical, political,
@@ -2016,11 +2015,11 @@ public final class Locale implements Cloneable, Serializable {
/**
* Calculated hashcode
*/
- private transient volatile int hashCodeValue = 0;
+ private transient volatile int hashCodeValue;
private static volatile Locale defaultLocale = initDefault();
- private static volatile Locale defaultDisplayLocale = null;
- private static volatile Locale defaultFormatLocale = null;
+ private static volatile Locale defaultDisplayLocale;
+ private static volatile Locale defaultFormatLocale;
private transient volatile String languageTag;
@@ -2207,9 +2206,9 @@ public final class Locale implements Cloneable, Serializable {
baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
}
- private static volatile String[] isoLanguages = null;
+ private static volatile String[] isoLanguages;
- private static volatile String[] isoCountries = null;
+ private static volatile String[] isoCountries;
private static String convertOldISOCodes(String language) {
// we accept both the old and the new ISO codes for the languages whose ISO
@@ -2851,7 +2850,7 @@ public final class Locale implements Cloneable, Serializable {
private final String range;
private final double weight;
- private volatile int hash = 0;
+ private volatile int hash;
/**
* Constructs a {@code LanguageRange} using the given {@code range}.
@@ -3108,14 +3107,17 @@ public final class Locale implements Cloneable, Serializable {
*/
@Override
public int hashCode() {
- if (hash == 0) {
- int result = 17;
- result = 37*result + range.hashCode();
+ int h = hash;
+ if (h == 0) {
+ h = 17;
+ h = 37*h + range.hashCode();
long bitsWeight = Double.doubleToLongBits(weight);
- result = 37*result + (int)(bitsWeight ^ (bitsWeight >>> 32));
- hash = result;
+ h = 37*h + (int)(bitsWeight ^ (bitsWeight >>> 32));
+ if (h != 0) {
+ hash = h;
+ }
}
- return hash;
+ return h;
}
/**
diff --git a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
index 3a6ac6f56a8..511611f574b 100644
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
@@ -950,7 +950,7 @@ public final class Pattern
* Boolean indicating this Pattern is compiled; this is necessary in order
* to lazily compile deserialized Patterns.
*/
- private transient volatile boolean compiled = false;
+ private transient volatile boolean compiled;
/**
* The normalized pattern string.
@@ -1332,7 +1332,6 @@ public final class Pattern
localCount = 0;
// if length > 0, the Pattern is lazily compiled
- compiled = false;
if (pattern.length() == 0) {
root = new Start(lastAccept);
matchRoot = lastAccept;
@@ -1377,7 +1376,6 @@ public final class Pattern
* equivalences of the characters.
*/
private void normalize() {
- boolean inCharClass = false;
int lastCodePoint = -1;
// Convert pattern into normalized form
@@ -1551,7 +1549,6 @@ public final class Pattern
// offset maintains the index in code units.
loop: for(int x=0, offset=0; x=0; y--) {
if (combClass[y] == combClass[x]) {
continue loop;
@@ -1566,8 +1563,7 @@ loop: for(int x=0, offset=0; x namedGroups() {
- if (namedGroups == null)
- namedGroups = new HashMap<>(2);
- return namedGroups;
+ Map groups = namedGroups;
+ if (groups == null) {
+ namedGroups = groups = new HashMap<>(2);
+ }
+ return groups;
}
/**
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
index a25db018b78..9d9a776a010 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -72,7 +72,7 @@ public
class ZipFile implements ZipConstants, Closeable {
private final String name; // zip file name
- private volatile boolean closeRequested = false;
+ private volatile boolean closeRequested;
private Source zsrc;
private ZipCoder zc;
@@ -366,7 +366,7 @@ class ZipFile implements ZipConstants, Closeable {
}
private class ZipFileInflaterInputStream extends InflaterInputStream {
- private volatile boolean closeRequested = false;
+ private volatile boolean closeRequested;
private boolean eof = false;
private final ZipFileInputStream zfin;
@@ -653,7 +653,7 @@ class ZipFile implements ZipConstants, Closeable {
* (possibly compressed) zip file entry.
*/
private class ZipFileInputStream extends InputStream {
- private volatile boolean closeRequested = false;
+ private volatile boolean closeRequested;
private long pos; // current position within entry data
protected long rem; // number of remaining bytes within entry
protected long size; // uncompressed size of this entry
diff --git a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
index c59ff195cc4..c54fc1a55ff 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
@@ -326,20 +326,22 @@ public final class LazyLoggers {
}
// Do not expose this outside of this package.
- private static volatile LoggerFinder provider = null;
+ private static volatile LoggerFinder provider;
private static LoggerFinder accessLoggerFinder() {
- if (provider == null) {
+ LoggerFinder prov = provider;
+ if (prov == null) {
// no need to lock: it doesn't matter if we call
// getLoggerFinder() twice - since LoggerFinder already caches
// the result.
// This is just an optimization to avoid the cost of calling
// doPrivileged every time.
final SecurityManager sm = System.getSecurityManager();
- provider = sm == null ? LoggerFinder.getLoggerFinder() :
+ prov = sm == null ? LoggerFinder.getLoggerFinder() :
AccessController.doPrivileged(
(PrivilegedAction)LoggerFinder::getLoggerFinder);
+ provider = prov;
}
- return provider;
+ return prov;
}
// Avoid using lambda here as lazy loggers could be created early
diff --git a/jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java b/jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
index 6ee80490102..c0480e9d497 100644
--- a/jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
@@ -23,7 +23,7 @@
* questions.
*/
-package sun.misc;
+package jdk.internal.math;
/**
* This class contains additional constants documenting limits of the
diff --git a/jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java b/jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
index d25f2017f6a..ba3ce9b8287 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
@@ -22,7 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package sun.misc;
+package jdk.internal.math;
import java.math.BigInteger;
import java.util.Arrays;
diff --git a/jdk/src/java.base/share/classes/sun/misc/FloatConsts.java b/jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FloatConsts.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
index 07396f8bca9..977a222278b 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FloatConsts.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
@@ -23,7 +23,7 @@
* questions.
*/
-package sun.misc;
+package jdk.internal.math;
/**
* This class contains additional constants documenting limits of the
diff --git a/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java b/jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
index 0c07520f13e..575255eb174 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
@@ -23,7 +23,7 @@
* questions.
*/
-package sun.misc;
+package jdk.internal.math;
import java.util.Arrays;
import java.util.regex.*;
diff --git a/jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java b/jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
index fc53920e398..0a560dc11e5 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
@@ -23,7 +23,7 @@
* questions.
*/
-package sun.misc;
+package jdk.internal.math;
import java.util.Arrays;
diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java b/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
index cec14ba5b42..4ce835f9a39 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
@@ -39,7 +39,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.function.Function;
import sun.misc.InnocuousThread;
-import sun.misc.ManagedLocalsThread;
/**
* CleanerImpl manages a set of object references and corresponding cleaning actions.
@@ -130,8 +129,8 @@ public final class CleanerImpl implements Runnable {
*/
public void run() {
Thread t = Thread.currentThread();
- ManagedLocalsThread mlThread = (t instanceof ManagedLocalsThread)
- ? (ManagedLocalsThread) t
+ InnocuousThread mlThread = (t instanceof InnocuousThread)
+ ? (InnocuousThread) t
: null;
while (!phantomCleanableList.isListEmpty() ||
!weakCleanableList.isListEmpty() ||
@@ -787,4 +786,3 @@ public final class CleanerImpl implements Runnable {
}
}
-
diff --git a/jdk/src/java.base/share/classes/sun/misc/VM.java b/jdk/src/java.base/share/classes/sun/misc/VM.java
index 37dc3b38fa1..4c83dfaf049 100644
--- a/jdk/src/java.base/share/classes/sun/misc/VM.java
+++ b/jdk/src/java.base/share/classes/sun/misc/VM.java
@@ -27,9 +27,6 @@ package sun.misc;
import static java.lang.Thread.State.*;
import java.util.Properties;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
public class VM {
@@ -288,10 +285,10 @@ public class VM {
}
/* Current count of objects pending for finalization */
- private static volatile int finalRefCount = 0;
+ private static volatile int finalRefCount;
/* Peak count of objects pending for finalization */
- private static volatile int peakFinalRefCount = 0;
+ private static volatile int peakFinalRefCount;
/*
* Gets the number of objects pending for finalization.
diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
index 43eff0435f4..13ede95ac41 100644
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
@@ -54,12 +54,12 @@ import sun.util.logging.PlatformLogger;
* @author jccollet
*/
public class HttpCapture {
- private File file = null;
+ private File file;
private boolean incoming = true;
- private BufferedWriter out = null;
- private static boolean initialized = false;
- private static volatile ArrayList patterns = null;
- private static volatile ArrayList capFiles = null;
+ private BufferedWriter out;
+ private static boolean initialized;
+ private static volatile ArrayList patterns;
+ private static volatile ArrayList capFiles;
private static synchronized void init() {
initialized = true;
diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
index c0b0d629d42..920b48d4b64 100644
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
@@ -98,7 +98,7 @@ public class HttpClient extends NetworkClient {
// from previous releases.
private static boolean retryPostProp = true;
- volatile boolean keepingAlive = false; /* this is a keep-alive connection */
+ volatile boolean keepingAlive; /* this is a keep-alive connection */
int keepAliveConnections = -1; /* number of keep-alives left */
/**Idle timeout value, in milliseconds. Zero means infinity,
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
index 2d0ef217e3c..8ed2c9f1317 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
@@ -51,14 +51,14 @@ abstract class AsynchronousServerSocketChannelImpl
protected final FileDescriptor fd;
// the local address to which the channel's socket is bound
- protected volatile InetSocketAddress localAddress = null;
+ protected volatile InetSocketAddress localAddress;
// need this lock to set local address
private final Object stateLock = new Object();
// close support
private ReadWriteLock closeLock = new ReentrantReadWriteLock();
- private volatile boolean open = true;
+ private volatile boolean closed;
// set true when accept operation is cancelled
private volatile boolean acceptKilled;
@@ -73,7 +73,7 @@ abstract class AsynchronousServerSocketChannelImpl
@Override
public final boolean isOpen() {
- return open;
+ return !closed;
}
/**
@@ -102,9 +102,9 @@ abstract class AsynchronousServerSocketChannelImpl
// synchronize with any threads using file descriptor/handle
closeLock.writeLock().lock();
try {
- if (!open)
+ if (closed)
return; // already closed
- open = false;
+ closed = true;
} finally {
closeLock.writeLock().unlock();
}
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
index 16a4d391881..3122b96a29f 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
@@ -54,8 +54,8 @@ abstract class AsynchronousSocketChannelImpl
// protects state, localAddress, and remoteAddress
protected final Object stateLock = new Object();
- protected volatile InetSocketAddress localAddress = null;
- protected volatile InetSocketAddress remoteAddress = null;
+ protected volatile InetSocketAddress localAddress;
+ protected volatile InetSocketAddress remoteAddress;
// State, increases monotonically
static final int ST_UNINITIALIZED = -1;
@@ -78,7 +78,7 @@ abstract class AsynchronousSocketChannelImpl
// close support
private final ReadWriteLock closeLock = new ReentrantReadWriteLock();
- private volatile boolean open = true;
+ private volatile boolean closed;
// set true when exclusive binding is on and SO_REUSEADDR is emulated
private boolean isReuseAddress;
@@ -106,7 +106,7 @@ abstract class AsynchronousSocketChannelImpl
@Override
public final boolean isOpen() {
- return open;
+ return !closed;
}
/**
@@ -135,9 +135,9 @@ abstract class AsynchronousSocketChannelImpl
// synchronize with any threads initiating asynchronous operations
closeLock.writeLock().lock();
try {
- if (!open)
+ if (closed)
return; // already closed
- open = false;
+ closed = true;
} finally {
closeLock.writeLock().unlock();
}
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 9d4a2e828c1..7eb987991c9 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -58,8 +58,8 @@ class DatagramChannelImpl
private final ProtocolFamily family;
// IDs of native threads doing reads and writes, for signalling
- private volatile long readerThread = 0;
- private volatile long writerThread = 0;
+ private volatile long readerThread;
+ private volatile long writerThread;
// Cached InetAddress and port for unconnected DatagramChannels
// used by receive0
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
index fe2ed230002..fa1eae73d59 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
@@ -46,7 +46,7 @@ public class DatagramSocketAdaptor
private final DatagramChannelImpl dc;
// Timeout "option" value for receives
- private volatile int timeout = 0;
+ private volatile int timeout;
// ## super will create a useless impl
private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
index 05bc5764062..1b00761f9f2 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
@@ -31,7 +31,7 @@ import java.nio.channels.*;
public class FileLockImpl
extends FileLock
{
- private volatile boolean valid = true;
+ private volatile boolean invalid;
FileLockImpl(FileChannel channel, long position, long size, boolean shared)
{
@@ -44,25 +44,25 @@ public class FileLockImpl
}
public boolean isValid() {
- return valid;
+ return !invalid;
}
void invalidate() {
assert Thread.holdsLock(this);
- valid = false;
+ invalid = true;
}
public synchronized void release() throws IOException {
Channel ch = acquiredBy();
if (!ch.isOpen())
throw new ClosedChannelException();
- if (valid) {
+ if (isValid()) {
if (ch instanceof FileChannelImpl)
((FileChannelImpl)ch).release(this);
else if (ch instanceof AsynchronousFileChannelImpl)
((AsynchronousFileChannelImpl)ch).release(this);
else throw new AssertionError();
- valid = false;
+ invalidate();
}
}
}
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
index 4d47b41ad9b..abe0e7ad277 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
@@ -43,8 +43,7 @@ class MembershipKeyImpl
private final NetworkInterface interf;
private final InetAddress source;
- // true when key is valid
- private volatile boolean valid = true;
+ private volatile boolean invalid;
// lock used when creating or accessing blockedSet
private Object stateLock = new Object();
@@ -134,12 +133,12 @@ class MembershipKeyImpl
}
public boolean isValid() {
- return valid;
+ return !invalid;
}
// package-private
void invalidate() {
- valid = false;
+ invalid = true;
}
public void drop() {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
index 525d3a1224c..27c46a9ca2c 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
@@ -32,7 +32,6 @@ import java.nio.channels.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
import sun.net.ExtendedOptionsImpl;
@@ -55,7 +54,7 @@ public class Net {
// -- Miscellaneous utilities --
- private static volatile boolean checkedIPv6 = false;
+ private static volatile boolean checkedIPv6;
private static volatile boolean isIPv6Available;
/**
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
index e7a2cbb73be..11d16b6068f 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
@@ -45,7 +45,7 @@ public class ServerSocketAdaptor // package-private
private final ServerSocketChannelImpl ssc;
// Timeout "option" value for accepts
- private volatile int timeout = 0;
+ private volatile int timeout;
public static ServerSocket create(ServerSocketChannelImpl ssc) {
try {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
index 0274c2e0753..2a427f1a352 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
@@ -54,7 +54,7 @@ class ServerSocketChannelImpl
private int fdVal;
// ID of native thread currently blocked in this channel, for signalling
- private volatile long thread = 0;
+ private volatile long thread;
// Lock held by thread currently blocked in this channel
private final Object lock = new Object();
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
index d115b7aaf60..bf43c8b2317 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -26,13 +26,11 @@
package sun.nio.ch;
import java.io.*;
-import java.lang.ref.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
-import java.util.*;
// Make a socket channel look like a socket.
@@ -55,7 +53,7 @@ public class SocketAdaptor
private final SocketChannelImpl sc;
// Timeout "option" value for reads
- private volatile int timeout = 0;
+ private volatile int timeout;
private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
super((SocketImpl) null);
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
index 0b3a3828ef3..c4965e1111b 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -56,8 +56,8 @@ class SocketChannelImpl
private final int fdVal;
// IDs of native threads doing reads and writes, for signalling
- private volatile long readerThread = 0;
- private volatile long writerThread = 0;
+ private volatile long readerThread;
+ private volatile long writerThread;
// Lock held by current reading or connecting thread
private final Object readLock = new Object();
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
index fd428149999..bb8df722927 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
@@ -25,13 +25,10 @@
package sun.nio.ch;
-import java.lang.ref.SoftReference;
import java.lang.reflect.*;
-import java.io.IOException;
import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
@@ -295,7 +292,7 @@ public class Util {
return pageSize;
}
- private static volatile Constructor> directByteBufferConstructor = null;
+ private static volatile Constructor> directByteBufferConstructor;
private static void initDBBConstructor() {
AccessController.doPrivileged(new PrivilegedAction() {
@@ -340,7 +337,7 @@ public class Util {
return dbb;
}
- private static volatile Constructor> directByteBufferRConstructor = null;
+ private static volatile Constructor> directByteBufferRConstructor;
private static void initDBBRConstructor() {
AccessController.doPrivileged(new PrivilegedAction() {
@@ -388,7 +385,7 @@ public class Util {
// -- Bug compatibility --
- private static volatile String bugLevel = null;
+ private static volatile String bugLevel;
static boolean atBugLevel(String bl) { // package-private
if (bugLevel == null) {
diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java b/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
index e878d6d4891..eedf00480aa 100644
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
@@ -39,10 +39,10 @@ public class StreamDecoder extends Reader
private static final int MIN_BYTE_BUFFER_SIZE = 32;
private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
- private volatile boolean isOpen = true;
+ private volatile boolean closed;
private void ensureOpen() throws IOException {
- if (!isOpen)
+ if (closed)
throw new IOException("Stream closed");
}
@@ -188,15 +188,15 @@ public class StreamDecoder extends Reader
public void close() throws IOException {
synchronized (lock) {
- if (!isOpen)
+ if (closed)
return;
implClose();
- isOpen = false;
+ closed = true;
}
}
private boolean isOpen() {
- return isOpen;
+ return !closed;
}
diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java b/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
index b41f93c038c..ccf3c63dbd0 100644
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
@@ -38,10 +38,10 @@ public class StreamEncoder extends Writer
private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
- private volatile boolean isOpen = true;
+ private volatile boolean closed;
private void ensureOpen() throws IOException {
- if (!isOpen)
+ if (closed)
throw new IOException("Stream closed");
}
@@ -156,15 +156,15 @@ public class StreamEncoder extends Writer
public void close() throws IOException {
synchronized (lock) {
- if (!isOpen)
+ if (closed)
return;
implClose();
- isOpen = false;
+ closed = true;
}
}
private boolean isOpen() {
- return isOpen;
+ return !closed;
}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java b/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
index dfecd17423e..68e1a7c0c43 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
@@ -44,9 +44,9 @@ class MethodAccessorGenerator extends AccessorGenerator {
// Only used if forSerialization is true
private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;
- private static volatile int methodSymnum = 0;
- private static volatile int constructorSymnum = 0;
- private static volatile int serializationConstructorSymnum = 0;
+ private static volatile int methodSymnum;
+ private static volatile int constructorSymnum;
+ private static volatile int serializationConstructorSymnum;
private Class> declaringClass;
private Class>[] parameterTypes;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
index da509b6081a..2f6bdee2f93 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
@@ -299,7 +299,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
}});
}
- private transient volatile Method[] memberMethods = null;
+ private transient volatile Method[] memberMethods;
/**
* Validates that a method is structurally appropriate for an
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
index 9f76d19792f..57a3e1e8aa6 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
@@ -1105,41 +1105,6 @@ final class CipherBox {
return fragLen;
}
-
- /*
- * Is this cipher available?
- *
- * This method can only be called by CipherSuite.BulkCipher.isAvailable()
- * to test the availability of a cipher suites. Please DON'T use it in
- * other places, otherwise, the behavior may be unexpected because we may
- * initialize AEAD cipher improperly in the method.
- */
- Boolean isAvailable() {
- // We won't know whether a cipher for a particular key size is
- // available until the cipher is successfully initialized.
- //
- // We do not initialize AEAD cipher in the constructor. Need to
- // initialize the cipher to ensure that the AEAD mode for a
- // particular key size is supported.
- if (cipherType == AEAD_CIPHER) {
- try {
- Authenticator authenticator =
- new Authenticator(protocolVersion);
- byte[] nonce = authenticator.sequenceNumber();
- byte[] iv = Arrays.copyOf(fixedIv,
- fixedIv.length + nonce.length);
- System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
- GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-
- cipher.init(mode, key, spec, random);
- } catch (Exception e) {
- return Boolean.FALSE;
- }
- } // Otherwise, we have initialized the cipher in the constructor.
-
- return Boolean.TRUE;
- }
-
/**
* Sanity check the length of a fragment before decryption.
*
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
index 65a110b479e..fa6c5ad34bb 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
@@ -77,12 +77,6 @@ final class CipherSuite implements Comparable {
// minimum priority for default enabled CipherSuites
static final int DEFAULT_SUITES_PRIORITY = 300;
- // Flag indicating if CipherSuite availability can change dynamically.
- // This is the case when we rely on a JCE cipher implementation that
- // may not be available in the installed JCE providers.
- // It is true because we might not have an ECC implementation.
- static final boolean DYNAMIC_AVAILABILITY = true;
-
private static final boolean ALLOW_ECC = Debug.getBooleanProperty
("com.sun.net.ssl.enableECC", true);
@@ -176,9 +170,6 @@ final class CipherSuite implements Comparable {
* Return whether this CipherSuite is available for use. A
* CipherSuite may be unavailable even if it is supported
* (i.e. allowed == true) if the required JCE cipher is not installed.
- * In some configuration, this situation may change over time, call
- * CipherSuiteList.clearAvailableCache() before this method to obtain
- * the most current status.
*/
boolean isAvailable() {
return allowed && keyExchange.isAvailable() && cipher.isAvailable();
@@ -471,10 +462,6 @@ final class CipherSuite implements Comparable {
B_AES_128_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 16, 12, 4, true),
B_AES_256_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 32, 12, 4, true);
- // Map BulkCipher -> Boolean(available)
- private static final Map availableCache =
- new HashMap<>(8);
-
// descriptive name including key size, e.g. AES/128
final String description;
@@ -518,6 +505,9 @@ final class CipherSuite implements Comparable {
// The secure random used to detect the cipher availability.
private static final SecureRandom secureRandom;
+ // runtime availability
+ private final boolean isAvailable;
+
static {
try {
secureRandom = JsseJce.getSecureRandom();
@@ -542,6 +532,17 @@ final class CipherSuite implements Comparable {
this.expandedKeySize = expandedKeySize;
this.exportable = true;
+
+ // availability of this bulk cipher
+ //
+ // Currently all supported ciphers except AES are always available
+ // via the JSSE internal implementations. We also assume AES/128 of
+ // CBC mode is always available since it is shipped with the SunJCE
+ // provider. However, AES/256 is unavailable when the default JCE
+ // policy jurisdiction files are installed because of key length
+ // restrictions.
+ this.isAvailable =
+ allowed ? isUnlimited(keySize, transformation) : false;
}
BulkCipher(String transformation, CipherType cipherType, int keySize,
@@ -558,6 +559,17 @@ final class CipherSuite implements Comparable {
this.expandedKeySize = keySize;
this.exportable = false;
+
+ // availability of this bulk cipher
+ //
+ // Currently all supported ciphers except AES are always available
+ // via the JSSE internal implementations. We also assume AES/128 of
+ // CBC mode is always available since it is shipped with the SunJCE
+ // provider. However, AES/256 is unavailable when the default JCE
+ // policy jurisdiction files are installed because of key length
+ // restrictions.
+ this.isAvailable =
+ allowed ? isUnlimited(keySize, transformation) : false;
}
/**
@@ -575,86 +587,29 @@ final class CipherSuite implements Comparable {
/**
* Test if this bulk cipher is available. For use by CipherSuite.
- *
- * Currently all supported ciphers except AES are always available
- * via the JSSE internal implementations. We also assume AES/128 of
- * CBC mode is always available since it is shipped with the SunJCE
- * provider. However, AES/256 is unavailable when the default JCE
- * policy jurisdiction files are installed because of key length
- * restrictions, and AEAD is unavailable when the underlying providers
- * do not support AEAD/GCM mode.
*/
boolean isAvailable() {
- if (allowed == false) {
- return false;
+ return this.isAvailable;
+ }
+
+ private static boolean isUnlimited(int keySize, String transformation) {
+ int keySizeInBits = keySize * 8;
+ if (keySizeInBits > 128) { // need the JCE unlimited
+ // strength jurisdiction policy
+ try {
+ if (Cipher.getMaxAllowedKeyLength(
+ transformation) < keySizeInBits) {
+
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
}
- if ((this == B_AES_256) ||
- (this.cipherType == CipherType.AEAD_CIPHER)) {
- return isAvailable(this);
- }
-
- // always available
return true;
}
- // for use by CipherSuiteList.clearAvailableCache();
- static synchronized void clearAvailableCache() {
- if (DYNAMIC_AVAILABILITY) {
- availableCache.clear();
- }
- }
-
- private static synchronized boolean isAvailable(BulkCipher cipher) {
- Boolean b = availableCache.get(cipher);
- if (b == null) {
- int keySizeInBits = cipher.keySize * 8;
- if (keySizeInBits > 128) { // need the JCE unlimited
- // strength jurisdiction policy
- try {
- if (Cipher.getMaxAllowedKeyLength(
- cipher.transformation) < keySizeInBits) {
- b = Boolean.FALSE;
- }
- } catch (Exception e) {
- b = Boolean.FALSE;
- }
- }
-
- if (b == null) {
- b = Boolean.FALSE; // may be reset to TRUE if
- // the cipher is available
- CipherBox temporary = null;
- try {
- SecretKey key = new SecretKeySpec(
- new byte[cipher.expandedKeySize],
- cipher.algorithm);
- IvParameterSpec iv;
- if (cipher.cipherType == CipherType.AEAD_CIPHER) {
- iv = new IvParameterSpec(
- new byte[cipher.fixedIvSize]);
- } else {
- iv = new IvParameterSpec(new byte[cipher.ivSize]);
- }
- temporary = cipher.newCipher(
- ProtocolVersion.DEFAULT_TLS,
- key, iv, secureRandom, true);
- b = temporary.isAvailable();
- } catch (NoSuchAlgorithmException e) {
- // not available
- } finally {
- if (temporary != null) {
- temporary.dispose();
- }
- }
- }
-
- availableCache.put(cipher, b);
- }
-
- return b.booleanValue();
- }
-
@Override
public String toString() {
return description;
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
index 19dc90fa4c5..491bffa85ba 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -74,24 +74,12 @@ final class CipherSuiteList {
throw new IllegalArgumentException("CipherSuites may not be null");
}
cipherSuites = new ArrayList(names.length);
- // refresh available cache once if a CipherSuite is not available
- // (maybe new JCE providers have been installed)
- boolean refreshed = false;
for (int i = 0; i < names.length; i++) {
String suiteName = names[i];
CipherSuite suite = CipherSuite.valueOf(suiteName);
if (suite.isAvailable() == false) {
- if (refreshed == false) {
- // clear the cache so that the isAvailable() call below
- // does a full check
- clearAvailableCache();
- refreshed = true;
- }
- // still missing?
- if (suite.isAvailable() == false) {
- throw new IllegalArgumentException("Cannot support "
- + suiteName + " with currently installed providers");
- }
+ throw new IllegalArgumentException("Cannot support "
+ + suiteName + " with currently installed providers");
}
cipherSuites.add(suite);
}
@@ -195,16 +183,4 @@ final class CipherSuiteList {
}
s.putBytes16(suiteBytes);
}
-
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- */
- static synchronized void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
}
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
index 43d62b60152..aebc7c09c08 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
@@ -55,11 +55,6 @@ final class JsseJce {
private static final ProviderList fipsProviderList;
- // Flag indicating whether EC crypto is available.
- // If null, then we have not checked yet.
- // If yes, then all the EC based crypto we need is available.
- private static Boolean ecAvailable;
-
// Flag indicating whether Kerberos crypto is available.
// If true, then all the Kerberos-based crypto we need is available.
private static final boolean kerberosAvailable;
@@ -180,24 +175,8 @@ final class JsseJce {
// no instantiation of this class
}
- static synchronized boolean isEcAvailable() {
- if (ecAvailable == null) {
- try {
- JsseJce.getSignature(SIGNATURE_ECDSA);
- JsseJce.getSignature(SIGNATURE_RAWECDSA);
- JsseJce.getKeyAgreement("ECDH");
- JsseJce.getKeyFactory("EC");
- JsseJce.getKeyPairGenerator("EC");
- ecAvailable = true;
- } catch (Exception e) {
- ecAvailable = false;
- }
- }
- return ecAvailable;
- }
-
- static synchronized void clearEcAvailable() {
- ecAvailable = null;
+ static boolean isEcAvailable() {
+ return EcAvailability.isAvailable;
}
static boolean isKerberosAvailable() {
@@ -399,4 +378,27 @@ final class JsseJce {
}
}
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static class EcAvailability {
+ // Is EC crypto available?
+ private final static boolean isAvailable;
+
+ static {
+ boolean mediator = true;
+ try {
+ JsseJce.getSignature(SIGNATURE_ECDSA);
+ JsseJce.getSignature(SIGNATURE_RAWECDSA);
+ JsseJce.getKeyAgreement("ECDH");
+ JsseJce.getKeyFactory("EC");
+ JsseJce.getKeyPairGenerator("EC");
+ } catch (Exception e) {
+ mediator = false;
+ }
+
+ isAvailable = mediator;
+ }
+ }
}
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
index cac13df0184..15b420da172 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -52,18 +52,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
private X509TrustManager trustManager;
private SecureRandom secureRandom;
- // supported and default protocols
- private ProtocolList defaultServerProtocolList;
- private ProtocolList defaultClientProtocolList;
- private ProtocolList supportedProtocolList;
-
- // supported and default cipher suites
- private CipherSuiteList defaultServerCipherSuiteList;
- private CipherSuiteList defaultClientCipherSuiteList;
- private CipherSuiteList supportedCipherSuiteList;
-
// DTLS cookie exchange manager
- private HelloCookieManager helloCookieManager;
+ private volatile HelloCookieManager helloCookieManager;
private StatusResponseManager statusResponseManager;
@@ -117,6 +107,7 @@ public abstract class SSLContextImpl extends SSLContextSpi {
if (debug != null && Debug.isOn("sslctx")) {
System.out.println("done seeding SecureRandom");
}
+
isInitialized = true;
}
@@ -242,13 +233,20 @@ public abstract class SSLContextImpl extends SSLContextSpi {
return ephemeralKeyManager;
}
+ // Used for DTLS in server mode only, see ServerHandshaker.
HelloCookieManager getHelloCookieManager() {
if (!isInitialized) {
throw new IllegalStateException("SSLContext is not initialized");
}
- if (helloCookieManager == null) {
- helloCookieManager = getHelloCookieManager(secureRandom);
+ if (helloCookieManager != null) {
+ return helloCookieManager;
+ }
+
+ synchronized (this) {
+ if (helloCookieManager == null) {
+ helloCookieManager = getHelloCookieManager(secureRandom);
+ }
}
return helloCookieManager;
@@ -263,78 +261,34 @@ public abstract class SSLContextImpl extends SSLContextSpi {
return statusResponseManager;
}
- abstract SSLParameters getDefaultServerSSLParams();
- abstract SSLParameters getDefaultClientSSLParams();
- abstract SSLParameters getSupportedSSLParams();
-
// Get supported ProtocolList.
- ProtocolList getSuportedProtocolList() {
- if (supportedProtocolList == null) {
- supportedProtocolList =
- new ProtocolList(getSupportedSSLParams().getProtocols());
- }
+ abstract ProtocolList getSuportedProtocolList();
- return supportedProtocolList;
- }
+ // Get default ProtocolList for server mode.
+ abstract ProtocolList getServerDefaultProtocolList();
+
+ // Get default ProtocolList for client mode.
+ abstract ProtocolList getClientDefaultProtocolList();
+
+ // Get supported CipherSuiteList.
+ abstract CipherSuiteList getSupportedCipherSuiteList();
+
+ // Get default CipherSuiteList for server mode.
+ abstract CipherSuiteList getServerDefaultCipherSuiteList();
+
+ // Get default CipherSuiteList for client mode.
+ abstract CipherSuiteList getClientDefaultCipherSuiteList();
// Get default ProtocolList.
ProtocolList getDefaultProtocolList(boolean roleIsServer) {
- if (roleIsServer) {
- if (defaultServerProtocolList == null) {
- defaultServerProtocolList = new ProtocolList(
- getDefaultServerSSLParams().getProtocols());
- }
-
- return defaultServerProtocolList;
- } else {
- if (defaultClientProtocolList == null) {
- defaultClientProtocolList = new ProtocolList(
- getDefaultClientSSLParams().getProtocols());
- }
-
- return defaultClientProtocolList;
- }
- }
-
- // Get supported CipherSuiteList.
- CipherSuiteList getSupportedCipherSuiteList() {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (supportedCipherSuiteList == null) {
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- getSuportedProtocolList(), false);
- }
-
- return supportedCipherSuiteList;
- }
+ return roleIsServer ? getServerDefaultProtocolList()
+ : getClientDefaultProtocolList();
}
// Get default CipherSuiteList.
CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (roleIsServer) {
- if (defaultServerCipherSuiteList == null) {
- defaultServerCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(true), true);
- }
-
- return defaultServerCipherSuiteList;
- } else {
- if (defaultClientCipherSuiteList == null) {
- defaultClientCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(false), true);
- }
-
- return defaultClientCipherSuiteList;
- }
- }
+ return roleIsServer ? getServerDefaultCipherSuiteList()
+ : getClientDefaultCipherSuiteList();
}
/**
@@ -342,8 +296,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultProtocolList(ProtocolList protocols) {
- return (protocols == defaultServerProtocolList) ||
- (protocols == defaultClientProtocolList);
+ return (protocols == getServerDefaultProtocolList()) ||
+ (protocols == getClientDefaultProtocolList());
}
/**
@@ -351,8 +305,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
*/
boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
- return (cipherSuites == defaultClientCipherSuiteList) ||
- (cipherSuites == defaultServerCipherSuiteList);
+ return (cipherSuites == getServerDefaultCipherSuiteList()) ||
+ (cipherSuites == getClientDefaultCipherSuiteList());
}
/*
@@ -405,24 +359,6 @@ public abstract class SSLContextImpl extends SSLContextSpi {
return new CipherSuiteList(suites);
}
- /**
- * Clear cache of available ciphersuites. If we support all ciphers
- * internally, there is no need to clear the cache and calling this
- * method has no effect.
- *
- * Note that every call to clearAvailableCache() and the maintenance of
- * cipher suites need to be synchronized with this instance.
- */
- private void clearAvailableCache() {
- if (CipherSuite.DYNAMIC_AVAILABILITY) {
- supportedCipherSuiteList = null;
- defaultServerCipherSuiteList = null;
- defaultClientCipherSuiteList = null;
- CipherSuite.BulkCipher.clearAvailableCache();
- JsseJce.clearEcAvailable();
- }
- }
-
private static String[] getAvailableProtocols(
ProtocolVersion[] protocolCandidates) {
@@ -479,31 +415,28 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
private abstract static class AbstractTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
- // candidates for available protocols
- ProtocolVersion[] candidates;
-
if (SunJSSE.isFIPS()) {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.TLS10.name,
ProtocolVersion.TLS11.name,
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.SSL20Hello.name,
ProtocolVersion.SSL30.name,
ProtocolVersion.TLS10.name,
@@ -511,28 +444,40 @@ public abstract class SSLContextImpl extends SSLContextSpi {
ProtocolVersion.TLS12.name
});
- candidates = new ProtocolVersion[] {
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL20Hello,
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -552,30 +497,35 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
public static final class TLS10Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -585,32 +535,37 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
public static final class TLS11Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -620,34 +575,39 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
public static final class TLS12Context extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
} else {
- candidates = new ProtocolVersion[] {
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.SSL30,
ProtocolVersion.TLS10,
ProtocolVersion.TLS11,
ProtocolVersion.TLS12
- };
+ }));
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -719,7 +679,9 @@ public abstract class SSLContextImpl extends SSLContextSpi {
*/
private static class CustomizedTLSContext extends AbstractTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -766,11 +728,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
candidates = customizedTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -781,8 +745,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -795,71 +764,53 @@ public abstract class SSLContextImpl extends SSLContextSpi {
// use the default constructor and methods
}
- /*
- * The SSLContext implementation for default "Default" algorithm
- *
- * @see SSLContext
- */
- public static final class DefaultSSLContext extends CustomizedTLSContext {
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultManagersHolder {
private static final String NONE = "NONE";
private static final String P11KEYSTORE = "PKCS11";
- private static volatile SSLContextImpl defaultImpl;
+ private static final TrustManager[] trustManagers;
+ private static final KeyManager[] keyManagers;
- private static TrustManager[] defaultTrustManagers;
- private static KeyManager[] defaultKeyManagers;
+ static Exception reservedException = null;
- public DefaultSSLContext() throws Exception {
+ static {
+ TrustManager[] tmMediator;
try {
- super.engineInit(getDefaultKeyManager(),
- getDefaultTrustManager(), null);
+ tmMediator = getTrustManagers();
} catch (Exception e) {
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("default context init failed: " + e);
+ reservedException = e;
+ tmMediator = new TrustManager[0];
+ }
+ trustManagers = tmMediator;
+
+ if (reservedException == null) {
+ KeyManager[] kmMediator;
+ try {
+ kmMediator = getKeyManagers();
+ } catch (Exception e) {
+ reservedException = e;
+ kmMediator = new KeyManager[0];
}
- throw e;
- }
-
- if (defaultImpl == null) {
- defaultImpl = this;
+ keyManagers = kmMediator;
+ } else {
+ keyManagers = new KeyManager[0];
}
}
- @Override
- protected void engineInit(KeyManager[] km, TrustManager[] tm,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException
- ("Default SSLContext is initialized automatically");
- }
-
- static synchronized SSLContextImpl getDefaultImpl() throws Exception {
- if (defaultImpl == null) {
- new DefaultSSLContext();
- }
- return defaultImpl;
- }
-
- private static synchronized TrustManager[] getDefaultTrustManager()
- throws Exception {
- if (defaultTrustManagers != null) {
- return defaultTrustManagers;
- }
-
+ private static TrustManager[] getTrustManagers() throws Exception {
KeyStore ks =
TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
- defaultTrustManagers = tmf.getTrustManagers();
- return defaultTrustManagers;
+ return tmf.getTrustManagers();
}
- private static synchronized KeyManager[] getDefaultKeyManager()
- throws Exception {
- if (defaultKeyManagers != null) {
- return defaultKeyManagers;
- }
+ private static KeyManager[] getKeyManagers() throws Exception {
final Map props = new HashMap<>();
AccessController.doPrivileged(
@@ -956,8 +907,71 @@ public abstract class SSLContextImpl extends SSLContextSpi {
kmf.init(ks, passwd);
}
- defaultKeyManagers = kmf.getKeyManagers();
- return defaultKeyManagers;
+ return kmf.getKeyManagers();
+ }
+ }
+
+ // lazy initialization holder class idiom for static default parameters
+ //
+ // See Effective Java Second Edition: Item 71.
+ private static final class DefaultSSLContextHolder {
+
+ private static final SSLContextImpl sslContext;
+ static Exception reservedException = null;
+
+ static {
+ SSLContextImpl mediator = null;
+ if (DefaultManagersHolder.reservedException != null) {
+ reservedException = DefaultManagersHolder.reservedException;
+ } else {
+ try {
+ mediator = new DefaultSSLContext();
+ } catch (Exception e) {
+ reservedException = e;
+ }
+ }
+
+ sslContext = mediator;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for default "Default" algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class DefaultSSLContext extends CustomizedTLSContext {
+
+ // public constructor for SSLContext.getInstance("Default")
+ public DefaultSSLContext() throws Exception {
+ if (DefaultManagersHolder.reservedException != null) {
+ throw DefaultManagersHolder.reservedException;
+ }
+
+ try {
+ super.engineInit(DefaultManagersHolder.keyManagers,
+ DefaultManagersHolder.trustManagers, null);
+ } catch (Exception e) {
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("default context init failed: " + e);
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ protected void engineInit(KeyManager[] km, TrustManager[] tm,
+ SecureRandom sr) throws KeyManagementException {
+ throw new KeyManagementException
+ ("Default SSLContext is initialized automatically");
+ }
+
+ static SSLContextImpl getDefaultImpl() throws Exception {
+ if (DefaultSSLContextHolder.reservedException != null) {
+ throw DefaultSSLContextHolder.reservedException;
+ }
+
+ return DefaultSSLContextHolder.sslContext;
}
}
@@ -971,39 +985,50 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
private abstract static class AbstractDTLSContext extends SSLContextImpl {
- // parameters
- private static final SSLParameters defaultServerSSLParams;
- private static final SSLParameters supportedSSLParams;
+ private static final ProtocolList supportedProtocolList;
+ private static final ProtocolList serverDefaultProtocolList;
+
+ private static final CipherSuiteList supportedCipherSuiteList;
+ private static final CipherSuiteList serverDefaultCipherSuiteList;
static {
- // supported SSL parameters
- supportedSSLParams = new SSLParameters();
-
// Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
- supportedSSLParams.setProtocols(new String[] {
+ supportedProtocolList = new ProtocolList(new String[] {
ProtocolVersion.DTLS10.name,
ProtocolVersion.DTLS12.name
});
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for server mode
+ serverDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultServerSSLParams = new SSLParameters();
- defaultServerSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ supportedCipherSuiteList = getApplicableCipherSuiteList(
+ supportedProtocolList, false); // all supported
+ serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ serverDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultServerSSLParams() {
- return defaultServerSSLParams;
+ ProtocolList getSuportedProtocolList() {
+ return supportedProtocolList;
}
@Override
- SSLParameters getSupportedSSLParams() {
- return supportedSSLParams;
+ CipherSuiteList getSupportedCipherSuiteList() {
+ return supportedCipherSuiteList;
+ }
+
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
}
@Override
@@ -1028,22 +1053,28 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
public static final class DTLS10Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1053,23 +1084,29 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
public static final class DTLS12Context extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
static {
- // candidates for available protocols
- ProtocolVersion[] candidates = new ProtocolVersion[] {
+ // available protocols for client mode
+ clientDefaultProtocolList = new ProtocolList(
+ getAvailableProtocols(new ProtocolVersion[] {
ProtocolVersion.DTLS10,
ProtocolVersion.DTLS12
- };
+ }));
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
@@ -1079,7 +1116,9 @@ public abstract class SSLContextImpl extends SSLContextSpi {
* @see SSLContext
*/
private static class CustomizedDTLSContext extends AbstractDTLSContext {
- private static final SSLParameters defaultClientSSLParams;
+ private static final ProtocolList clientDefaultProtocolList;
+ private static final CipherSuiteList clientDefaultCipherSuiteList;
+
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -1119,11 +1158,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
candidates = customizedDTLSProtocols.toArray(candidates);
}
- defaultClientSSLParams = new SSLParameters();
- defaultClientSSLParams.setProtocols(
+ clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
+ clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+ clientDefaultProtocolList, true); // enabled only
} else {
- defaultClientSSLParams = null; // unlikely to be used
+ clientDefaultProtocolList = null; // unlikely to be used
+ clientDefaultCipherSuiteList = null; // unlikely to be used
}
}
@@ -1134,8 +1175,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
}
@Override
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ CipherSuiteList getClientDefaultCipherSuiteList() {
+ return clientDefaultCipherSuiteList;
}
}
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
index d021ec17ef4..b566b892eb9 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
@@ -130,7 +130,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
* also since counters make shorter debugging IDs than the big ones
* we use in the protocol for uniqueness-over-time.
*/
- private static volatile int counter = 0;
+ private static volatile int counter;
/*
* Use of session caches is globally enabled/disabled.
diff --git a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
index 8b716798f64..812778c02c0 100644
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
@@ -1290,7 +1290,7 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
implements Comparable {
final X500Principal issuer;
final BigInteger serial;
- volatile int hashcode = 0;
+ volatile int hashcode;
/**
* Create an X509IssuerSerial.
@@ -1358,13 +1358,16 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
* @return the hash code value
*/
public int hashCode() {
- if (hashcode == 0) {
- int result = 17;
- result = 37*result + issuer.hashCode();
- result = 37*result + serial.hashCode();
- hashcode = result;
+ int h = hashcode;
+ if (h == 0) {
+ h = 17;
+ h = 37*h + issuer.hashCode();
+ h = 37*h + serial.hashCode();
+ if (h != 0) {
+ hashcode = h;
+ }
}
- return hashcode;
+ return h;
}
@Override
diff --git a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
index 535f9159293..59fae3b7c0e 100644
--- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
@@ -25,13 +25,6 @@
package sun.util.calendar;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -76,7 +69,7 @@ public abstract class CalendarSystem {
/////////////////////// Calendar Factory Methods /////////////////////////
- private static volatile boolean initialized = false;
+ private static volatile boolean initialized;
// Map of calendar names and calendar class names
private static ConcurrentMap names;
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java b/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
index 2f4da3d5960..62420d23351 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
@@ -46,7 +46,7 @@ public final class BaseLocale {
private final String region;
private final String variant;
- private volatile int hash = 0;
+ private volatile int hash;
// This method must be called only when creating the Locale.* constants.
private BaseLocale(String language, String region) {
@@ -147,7 +147,9 @@ public final class BaseLocale {
h = 31 * h + script.hashCode();
h = 31 * h + region.hashCode();
h = 31 * h + variant.hashCode();
- hash = h;
+ if (h != 0) {
+ hash = h;
+ }
}
return h;
}
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
index 5cb48a97d36..c9cdba78edc 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
@@ -114,20 +114,20 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
}
}
- private volatile BreakIteratorProvider breakIteratorProvider = null;
- private volatile CollatorProvider collatorProvider = null;
- private volatile DateFormatProvider dateFormatProvider = null;
- private volatile DateFormatSymbolsProvider dateFormatSymbolsProvider = null;
- private volatile DecimalFormatSymbolsProvider decimalFormatSymbolsProvider = null;
- private volatile NumberFormatProvider numberFormatProvider = null;
+ private volatile BreakIteratorProvider breakIteratorProvider;
+ private volatile CollatorProvider collatorProvider;
+ private volatile DateFormatProvider dateFormatProvider;
+ private volatile DateFormatSymbolsProvider dateFormatSymbolsProvider;
+ private volatile DecimalFormatSymbolsProvider decimalFormatSymbolsProvider;
+ private volatile NumberFormatProvider numberFormatProvider;
- private volatile CurrencyNameProvider currencyNameProvider = null;
- private volatile LocaleNameProvider localeNameProvider = null;
- private volatile TimeZoneNameProvider timeZoneNameProvider = null;
- private volatile CalendarDataProvider calendarDataProvider = null;
- private volatile CalendarNameProvider calendarNameProvider = null;
+ private volatile CurrencyNameProvider currencyNameProvider;
+ private volatile LocaleNameProvider localeNameProvider;
+ private volatile TimeZoneNameProvider timeZoneNameProvider;
+ private volatile CalendarDataProvider calendarDataProvider;
+ private volatile CalendarNameProvider calendarNameProvider;
- private volatile CalendarProvider calendarProvider = null;
+ private volatile CalendarProvider calendarProvider;
/*
* Getter methods for java.text.spi.* providers
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
index c17856ffe9a..e19a6c8c531 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
@@ -107,7 +107,7 @@ public abstract class LocaleProviderAdapter {
* Default fallback adapter type, which should return something meaningful in any case.
* This is either CLDR or FALLBACK.
*/
- static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter = null;
+ static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter;
/**
* Adapter lookup cache.
diff --git a/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java b/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
index ae1dce93f6b..4d31cf2834d 100644
--- a/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
+++ b/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
@@ -164,6 +164,6 @@ public abstract class OpenListResourceBundle extends ResourceBundle {
return new HashSet<>();
}
- private volatile Map lookup = null;
+ private volatile Map lookup;
private volatile Set keyset;
}
diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
index 8e437684f33..69e71c05f57 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
@@ -47,7 +47,7 @@ class SinkChannelImpl
int fdVal;
// ID of native thread doing write, for signalling
- private volatile long thread = 0;
+ private volatile long thread;
// Lock held by current reading thread
private final Object lock = new Object();
diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
index b1b4f9e36f0..7eea3ca0b72 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
@@ -47,7 +47,7 @@ class SourceChannelImpl
int fdVal;
// ID of native thread doing read, for signalling
- private volatile long thread = 0;
+ private volatile long thread;
// Lock held by current reading thread
private final Object lock = new Object();
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
index 9eb683b2bd7..d58677502d2 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
@@ -52,7 +52,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
private Map mimeTypeMap;
// set to true when file loaded
- private volatile boolean loaded = false;
+ private volatile boolean loaded;
public MimeTypesFileTypeDetector(Path filePath) {
mimeTypesFile = filePath;
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
index 182a57b94c2..f161bd3e0bf 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
@@ -69,15 +69,16 @@ public abstract class UnixFileSystemProvider
private void checkUri(URI uri) {
if (!uri.getScheme().equalsIgnoreCase(getScheme()))
throw new IllegalArgumentException("URI does not match this provider");
- if (uri.getAuthority() != null)
+ if (uri.getRawAuthority() != null)
throw new IllegalArgumentException("Authority component present");
- if (uri.getPath() == null)
+ String path = uri.getPath();
+ if (path == null)
throw new IllegalArgumentException("Path component is undefined");
- if (!uri.getPath().equals("/"))
+ if (!path.equals("/"))
throw new IllegalArgumentException("Path component should be '/'");
- if (uri.getQuery() != null)
+ if (uri.getRawQuery() != null)
throw new IllegalArgumentException("Query component present");
- if (uri.getFragment() != null)
+ if (uri.getRawFragment() != null)
throw new IllegalArgumentException("Fragment component present");
}
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
index b59ab4275ce..a0df3e3102e 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
@@ -49,11 +49,11 @@ class UnixUriUtils {
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
throw new IllegalArgumentException("URI scheme is not \"file\"");
- if (uri.getAuthority() != null)
+ if (uri.getRawAuthority() != null)
throw new IllegalArgumentException("URI has an authority component");
- if (uri.getFragment() != null)
+ if (uri.getRawFragment() != null)
throw new IllegalArgumentException("URI has a fragment component");
- if (uri.getQuery() != null)
+ if (uri.getRawQuery() != null)
throw new IllegalArgumentException("URI has a query component");
// compatibility with java.io.File
diff --git a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
index 6fa5efb1cbd..cb74298d3dc 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
@@ -119,7 +119,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
// Lock for interrupt triggering and clearing
private final Object interruptLock = new Object();
- private volatile boolean interruptTriggered = false;
+ private volatile boolean interruptTriggered;
WindowsSelectorImpl(SelectorProvider sp) throws IOException {
super(sp);
diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
index cf0d23fea2b..847ef1564b5 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
@@ -61,15 +61,16 @@ public class WindowsFileSystemProvider
private void checkUri(URI uri) {
if (!uri.getScheme().equalsIgnoreCase(getScheme()))
throw new IllegalArgumentException("URI does not match this provider");
- if (uri.getAuthority() != null)
+ if (uri.getRawAuthority() != null)
throw new IllegalArgumentException("Authority component present");
- if (uri.getPath() == null)
+ String path = uri.getPath();
+ if (path == null)
throw new IllegalArgumentException("Path component is undefined");
- if (!uri.getPath().equals("/"))
+ if (!path.equals("/"))
throw new IllegalArgumentException("Path component should be '/'");
- if (uri.getQuery() != null)
+ if (uri.getRawQuery() != null)
throw new IllegalArgumentException("Query component present");
- if (uri.getFragment() != null)
+ if (uri.getRawFragment() != null)
throw new IllegalArgumentException("Fragment component present");
}
diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
index 5748bbb02af..f95a913f448 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
@@ -123,16 +123,16 @@ class WindowsUriSupport {
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
throw new IllegalArgumentException("URI scheme is not \"file\"");
- if (uri.getFragment() != null)
+ if (uri.getRawFragment() != null)
throw new IllegalArgumentException("URI has a fragment component");
- if (uri.getQuery() != null)
+ if (uri.getRawQuery() != null)
throw new IllegalArgumentException("URI has a query component");
String path = uri.getPath();
if (path.equals(""))
throw new IllegalArgumentException("URI path component is empty");
// UNC
- String auth = uri.getAuthority();
+ String auth = uri.getRawAuthority();
if (auth != null && !auth.equals("")) {
String host = uri.getHost();
if (host == null)
diff --git a/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
index 5f05177be39..becfd0563ba 100644
--- a/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
@@ -289,6 +289,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* representationClass = String
* mimeType = "text/html"
*
+ *
+ * @since 1.8
*/
public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection");
@@ -301,6 +303,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* representationClass = String
* mimeType = "text/html"
*
+ *
+ * @since 1.8
*/
public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment");
@@ -314,6 +318,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* representationClass = String
* mimeType = "text/html"
*
+ *
+ * @since 1.8
*/
public static DataFlavor allHtmlFlavor = initHtmlDataFlavor("all");
diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
index 8e483468074..28e4f386d78 100644
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
@@ -24,6 +24,7 @@
*/
#import
+#include
#import "CMenuItem.h"
#import "CMenu.h"
@@ -40,7 +41,7 @@
@implementation CMenuItem
- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
-AWT_ASSERT_APPKIT_THREAD;
+ AWT_ASSERT_APPKIT_THREAD;
self = [super initWithPeer:peer];
if (self) {
if ([asSeparator boolValue]) {
@@ -63,13 +64,48 @@ AWT_ASSERT_APPKIT_THREAD;
- (BOOL) worksWhenModal {
return YES;
}
+// This is a method written using Carbon framework methods to remove
+// All modifiers including "Shift" modifier.
+// Example 1: Shortcut set is "Command Shift m" returns "m"
+// Example 2: Shortcut set is "Command m" returns "m"
+// Example 3: Shortcut set is "Alt Shift ," returns ","
+
+CFStringRef createStringForKey(CGKeyCode keyCode)
+{
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+// currentKeyboard now contains the current input source
+ CFDataRef layoutData =
+ TISGetInputSourceProperty(currentKeyboard,
+ kTISPropertyUnicodeKeyLayoutData);
+// the UNICODE keyLayout is fetched from currentKeyboard in layoutData
+ const UCKeyboardLayout *keyboardLayout =
+ (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+// A read-only data pointer is fetched from layoutData
+ UInt32 keysDown = 0;
+ UniChar chars[4];
+ UniCharCount realLength;
+
+ UCKeyTranslate(keyboardLayout,
+ keyCode,
+ kUCKeyActionDisplay,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysBit,
+ &keysDown,
+ sizeof(chars) / sizeof(chars[0]),
+ &realLength,
+ chars);
+ CFRelease(currentKeyboard);
+// Converts keyCode, modifier and dead-key state into UNICODE characters
+ return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
// Events
- (void)handleAction:(NSMenuItem *)sender {
-AWT_ASSERT_APPKIT_THREAD;
+ AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
-JNF_COCOA_ENTER(env);
-
+ JNF_COCOA_ENTER(env);
+
// If we are called as a result of user pressing a shortcut, do nothing,
// because AVTView has already sent corresponding key event to the Java
// layer from performKeyEquivalent.
@@ -82,31 +118,37 @@ JNF_COCOA_ENTER(env);
NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
if ([currEvent type] == NSKeyDown) {
NSString *menuKey = [sender keyEquivalent];
- NSString *eventKey = [currEvent charactersIgnoringModifiers];
-
- // Apple uses characters from private Unicode range for some of the
- // keys, so we need to do the same translation here that we do
- // for the regular key down events
- if ([eventKey length] == 1) {
- unichar origChar = [eventKey characterAtIndex:0];
- unichar newChar = NsCharToJavaChar(origChar, 0);
- if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
- newChar = origChar;
- }
-
- eventKey = [NSString stringWithCharacters: &newChar length: 1];
- }
-
+// If shortcut is "Command Shift ," the menuKey gets the value ","
+// But [currEvent charactersIgnoringModifiers]; returns "<" and not ","
+// because the charactersIgnoreingModifiers does not ignore "Shift"
+// So a shortcut like "Command Shift m" will return "M" where as the
+// MenuKey will have the value "m". To remove this issue the below
+// createStringForKey is used.
+ NSString *eventKey = createStringForKey([currEvent keyCode]);
+
+// Apple uses characters from private Unicode range for some of the
+// keys, so we need to do the same translation here that we do
+// for the regular key down events
+ if ([eventKey length] == 1) {
+ unichar origChar = [eventKey characterAtIndex:0];
+ unichar newChar = NsCharToJavaChar(origChar, 0);
+ if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
+ newChar = origChar;
+ }
+
+ eventKey = [NSString stringWithCharacters: &newChar length: 1];
+ }
+
NSWindow *keyWindow = [NSApp keyWindow];
if ([menuKey isEqualToString:eventKey] && keyWindow != nil) {
return;
}
}
-
+
if (fIsCheckbox) {
static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem");
static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V");
-
+
// Send the opposite of what's currently checked -- the action
// indicates what state we're going to.
NSInteger state = [sender state];
@@ -115,26 +157,26 @@ JNF_COCOA_ENTER(env);
} else {
static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem");
static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event)
-
+
NSUInteger modifiers = [currEvent modifierFlags];
jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO);
-
+
JNFCallVoidMethod(env, fPeer, jm_handleAction, UTC(currEvent), javaModifiers); // AWT_THREADING Safe (event)
}
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
-
+
NSUInteger modifierMask = 0;
-
+
if (![theKeyEquivalent isEqualToString:@""]) {
// Force the key equivalent to lower case if not using the shift key.
// Otherwise AppKit will draw a Shift glyph in the menu.
if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) == 0) {
theKeyEquivalent = [theKeyEquivalent lowercaseString];
}
-
+
// Hack for the question mark -- SHIFT and / means use the question mark.
if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) != 0 &&
[theKeyEquivalent isEqualToString:@"/"])
@@ -142,10 +184,10 @@ JNF_COCOA_EXIT(env);
theKeyEquivalent = @"?";
modifiers &= ~java_awt_event_KeyEvent_SHIFT_MASK;
}
-
+
modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
}
-
+
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[fMenuItem setKeyEquivalent:theKeyEquivalent];
[fMenuItem setKeyEquivalentModifierMask:modifierMask];
@@ -154,14 +196,14 @@ JNF_COCOA_EXIT(env);
}
- (void) setJavaImage:(NSImage *)theImage {
-
+
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setImage:theImage];
}];
}
- (void) setJavaToolTipText:(NSString *)theText {
-
+
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setToolTip:theText];
}];
@@ -169,11 +211,11 @@ JNF_COCOA_EXIT(env);
- (void)setJavaEnabled:(BOOL) enabled {
-
+
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
@synchronized(self) {
fIsEnabled = enabled;
-
+
// Warning: This won't work if the parent menu is disabled.
// See [CMenu syncFromJava]. We still need to call it here so
// the NSMenuItem itself gets properly updated.
@@ -183,7 +225,7 @@ JNF_COCOA_EXIT(env);
}
- (BOOL)isEnabled {
-
+
BOOL enabled = NO;
@synchronized(self) {
enabled = fIsEnabled;
@@ -193,7 +235,7 @@ JNF_COCOA_EXIT(env);
- (void)setJavaState:(BOOL)newState {
-
+
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setState:(newState ? NSOnState : NSOffState)];
}];
@@ -207,7 +249,7 @@ JNF_COCOA_EXIT(env);
- (void)dealloc {
[fMenuItem release];
fMenuItem = nil;
-
+
[super dealloc];
}
@@ -240,7 +282,7 @@ JNF_COCOA_EXIT(env);
/** Convert a Java keycode for SetMenuItemCmd */
static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
unichar macKey = 0;
-
+
if ((awtKey >= java_awt_event_KeyEvent_VK_0 && awtKey <= java_awt_event_KeyEvent_VK_9) ||
(awtKey >= java_awt_event_KeyEvent_VK_A && awtKey <= java_awt_event_KeyEvent_VK_Z))
{
@@ -255,68 +297,68 @@ static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
} else {
// Special characters
switch (awtKey) {
- case java_awt_event_KeyEvent_VK_BACK_QUOTE : macKey = '`'; break;
- case java_awt_event_KeyEvent_VK_QUOTE : macKey = '\''; break;
-
- case java_awt_event_KeyEvent_VK_ESCAPE : macKey = 0x1B; break;
- case java_awt_event_KeyEvent_VK_SPACE : macKey = ' '; break;
- case java_awt_event_KeyEvent_VK_PAGE_UP : macKey = NSPageUpFunctionKey; break;
- case java_awt_event_KeyEvent_VK_PAGE_DOWN : macKey = NSPageDownFunctionKey; break;
- case java_awt_event_KeyEvent_VK_END : macKey = NSEndFunctionKey; break;
- case java_awt_event_KeyEvent_VK_HOME : macKey = NSHomeFunctionKey; break;
-
- case java_awt_event_KeyEvent_VK_LEFT : macKey = NSLeftArrowFunctionKey; break;
- case java_awt_event_KeyEvent_VK_UP : macKey = NSUpArrowFunctionKey; break;
- case java_awt_event_KeyEvent_VK_RIGHT : macKey = NSRightArrowFunctionKey; break;
- case java_awt_event_KeyEvent_VK_DOWN : macKey = NSDownArrowFunctionKey; break;
-
- case java_awt_event_KeyEvent_VK_COMMA : macKey = ','; break;
-
- // Mac OS doesn't distinguish between the two '-' keys...
- case java_awt_event_KeyEvent_VK_MINUS :
- case java_awt_event_KeyEvent_VK_SUBTRACT : macKey = '-'; break;
-
- // or the two '.' keys...
- case java_awt_event_KeyEvent_VK_DECIMAL :
- case java_awt_event_KeyEvent_VK_PERIOD : macKey = '.'; break;
-
- // or the two '/' keys.
- case java_awt_event_KeyEvent_VK_DIVIDE :
- case java_awt_event_KeyEvent_VK_SLASH : macKey = '/'; break;
-
- case java_awt_event_KeyEvent_VK_SEMICOLON : macKey = ';'; break;
- case java_awt_event_KeyEvent_VK_EQUALS : macKey = '='; break;
-
- case java_awt_event_KeyEvent_VK_OPEN_BRACKET : macKey = '['; break;
- case java_awt_event_KeyEvent_VK_BACK_SLASH : macKey = '\\'; break;
- case java_awt_event_KeyEvent_VK_CLOSE_BRACKET : macKey = ']'; break;
-
- case java_awt_event_KeyEvent_VK_MULTIPLY : macKey = '*'; break;
- case java_awt_event_KeyEvent_VK_ADD : macKey = '+'; break;
-
- case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break;
- case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break;
- case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break;
- case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break;
- case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break;
- case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break;
- case java_awt_event_KeyEvent_VK_AMPERSAND : macKey = '&'; break;
- case java_awt_event_KeyEvent_VK_ASTERISK : macKey = '*'; break;
- case java_awt_event_KeyEvent_VK_QUOTEDBL : macKey = '\"'; break;
- case java_awt_event_KeyEvent_VK_LESS : macKey = '<'; break;
- case java_awt_event_KeyEvent_VK_GREATER : macKey = '>'; break;
- case java_awt_event_KeyEvent_VK_BRACELEFT : macKey = '{'; break;
- case java_awt_event_KeyEvent_VK_BRACERIGHT : macKey = '}'; break;
- case java_awt_event_KeyEvent_VK_AT : macKey = '@'; break;
- case java_awt_event_KeyEvent_VK_COLON : macKey = ':'; break;
- case java_awt_event_KeyEvent_VK_CIRCUMFLEX : macKey = '^'; break;
- case java_awt_event_KeyEvent_VK_DOLLAR : macKey = '$'; break;
- case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
- case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
- case java_awt_event_KeyEvent_VK_NUMBER_SIGN : macKey = '#'; break;
- case java_awt_event_KeyEvent_VK_PLUS : macKey = '+'; break;
- case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
- case java_awt_event_KeyEvent_VK_UNDERSCORE : macKey = '_'; break;
+ case java_awt_event_KeyEvent_VK_BACK_QUOTE : macKey = '`'; break;
+ case java_awt_event_KeyEvent_VK_QUOTE : macKey = '\''; break;
+
+ case java_awt_event_KeyEvent_VK_ESCAPE : macKey = 0x1B; break;
+ case java_awt_event_KeyEvent_VK_SPACE : macKey = ' '; break;
+ case java_awt_event_KeyEvent_VK_PAGE_UP : macKey = NSPageUpFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_PAGE_DOWN : macKey = NSPageDownFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_END : macKey = NSEndFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_HOME : macKey = NSHomeFunctionKey; break;
+
+ case java_awt_event_KeyEvent_VK_LEFT : macKey = NSLeftArrowFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_UP : macKey = NSUpArrowFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_RIGHT : macKey = NSRightArrowFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_DOWN : macKey = NSDownArrowFunctionKey; break;
+
+ case java_awt_event_KeyEvent_VK_COMMA : macKey = ','; break;
+
+ // Mac OS doesn't distinguish between the two '-' keys...
+ case java_awt_event_KeyEvent_VK_MINUS :
+ case java_awt_event_KeyEvent_VK_SUBTRACT : macKey = '-'; break;
+
+ // or the two '.' keys...
+ case java_awt_event_KeyEvent_VK_DECIMAL :
+ case java_awt_event_KeyEvent_VK_PERIOD : macKey = '.'; break;
+
+ // or the two '/' keys.
+ case java_awt_event_KeyEvent_VK_DIVIDE :
+ case java_awt_event_KeyEvent_VK_SLASH : macKey = '/'; break;
+
+ case java_awt_event_KeyEvent_VK_SEMICOLON : macKey = ';'; break;
+ case java_awt_event_KeyEvent_VK_EQUALS : macKey = '='; break;
+
+ case java_awt_event_KeyEvent_VK_OPEN_BRACKET : macKey = '['; break;
+ case java_awt_event_KeyEvent_VK_BACK_SLASH : macKey = '\\'; break;
+ case java_awt_event_KeyEvent_VK_CLOSE_BRACKET : macKey = ']'; break;
+
+ case java_awt_event_KeyEvent_VK_MULTIPLY : macKey = '*'; break;
+ case java_awt_event_KeyEvent_VK_ADD : macKey = '+'; break;
+
+ case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break;
+ case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break;
+ case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break;
+ case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break;
+ case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break;
+ case java_awt_event_KeyEvent_VK_AMPERSAND : macKey = '&'; break;
+ case java_awt_event_KeyEvent_VK_ASTERISK : macKey = '*'; break;
+ case java_awt_event_KeyEvent_VK_QUOTEDBL : macKey = '\"'; break;
+ case java_awt_event_KeyEvent_VK_LESS : macKey = '<'; break;
+ case java_awt_event_KeyEvent_VK_GREATER : macKey = '>'; break;
+ case java_awt_event_KeyEvent_VK_BRACELEFT : macKey = '{'; break;
+ case java_awt_event_KeyEvent_VK_BRACERIGHT : macKey = '}'; break;
+ case java_awt_event_KeyEvent_VK_AT : macKey = '@'; break;
+ case java_awt_event_KeyEvent_VK_COLON : macKey = ':'; break;
+ case java_awt_event_KeyEvent_VK_CIRCUMFLEX : macKey = '^'; break;
+ case java_awt_event_KeyEvent_VK_DOLLAR : macKey = '$'; break;
+ case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
+ case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
+ case java_awt_event_KeyEvent_VK_NUMBER_SIGN : macKey = '#'; break;
+ case java_awt_event_KeyEvent_VK_PLUS : macKey = '+'; break;
+ case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
+ case java_awt_event_KeyEvent_VK_UNDERSCORE : macKey = '_'; break;
}
}
return macKey;
@@ -330,27 +372,27 @@ static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
(JNIEnv *env, jobject peer,
- jlong menuItemObj, jstring label,
- jchar shortcutKey, jint shortcutKeyCode, jint mods)
+ jlong menuItemObj, jstring label,
+ jchar shortcutKey, jint shortcutKeyCode, jint mods)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
NSString *theLabel = JNFJavaToNSString(env, label);
NSString *theKeyEquivalent = nil;
unichar macKey = shortcutKey;
-
+
if (macKey == 0) {
macKey = AWTKeyToMacShortcut(shortcutKeyCode, (mods & java_awt_event_KeyEvent_SHIFT_MASK) != 0);
}
-
+
if (macKey != 0) {
unichar equivalent[1] = {macKey};
theKeyEquivalent = [NSString stringWithCharacters:equivalent length:1];
} else {
theKeyEquivalent = @"";
}
-
+
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaLabel:theLabel shortcut:theKeyEquivalent modifierMask:mods];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -362,10 +404,10 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetTooltip
(JNIEnv *env, jobject peer, jlong menuItemObj, jstring tooltip)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
NSString *theTooltip = JNFJavaToNSString(env, tooltip);
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaToolTipText:theTooltip];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -377,9 +419,9 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetImage
(JNIEnv *env, jobject peer, jlong menuItemObj, jlong image)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaImage:(NSImage*)jlong_to_ptr(image)];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -389,38 +431,38 @@ JNF_COCOA_EXIT(env);
*/
JNIEXPORT jlong JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeCreate
- (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
+(JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
{
-
+
CMenuItem *aCMenuItem = nil;
CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
-JNF_COCOA_ENTER(env);
-
+ JNF_COCOA_ENTER(env);
+
jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
-
+
NSMutableArray *args = nil;
-
+
// Create a new item....
if (isSeparator == JNI_TRUE) {
args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES], nil];
} else {
args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO], nil];
}
-
+
[ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
-
+
aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
-
+
if (aCMenuItem == nil) {
return 0L;
}
-
+
// and add it to the parent item.
[parentCMenu addJavaMenuItem: aCMenuItem];
-
+
// setLabel will be called after creation completes.
-
-JNF_COCOA_EXIT(env);
+
+ JNF_COCOA_EXIT(env);
return ptr_to_jlong(aCMenuItem);
}
@@ -433,10 +475,10 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetEnabled
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean enable)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
[item setJavaEnabled: (enable == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -448,10 +490,10 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetState
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean state)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
[item setJavaState: (state == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -463,8 +505,8 @@ JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetIsCheckbox
(JNIEnv *env, jobject peer, jlong menuItemObj)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
[item setIsCheckbox];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
index f25863955ec..7975efda580 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
@@ -874,13 +874,13 @@ public class JPEGMetadata extends IIOMetadata implements Cloneable {
return chroma;
}
- boolean idsAreJFIF = true;
+ boolean idsAreJFIF = false;
- for (int i = 0; i < sof.componentSpecs.length; i++) {
- int id = sof.componentSpecs[i].componentId;
- if ((id < 1) || (id >= sof.componentSpecs.length)) {
- idsAreJFIF = false;
- }
+ int cid0 = sof.componentSpecs[0].componentId;
+ int cid1 = sof.componentSpecs[1].componentId;
+ int cid2 = sof.componentSpecs[2].componentId;
+ if ((cid0 == 1) && (cid1 == 2) && (cid2 == 3)) {
+ idsAreJFIF = true;
}
if (idsAreJFIF) {
diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
index 0004904aa99..278882e5385 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
@@ -193,7 +193,17 @@ final class IDATOutputStream extends ImageOutputStreamImpl {
// Return to end of chunk and flush to minimize buffering
stream.seek(pos);
- stream.flushBefore(pos);
+ try {
+ stream.flushBefore(pos);
+ } catch (IOException e) {
+ /*
+ * If flushBefore() fails we try to access startPos in finally
+ * block of write_IDAT(). We should update startPos to avoid
+ * IndexOutOfBoundException while seek() is happening.
+ */
+ this.startPos = stream.getStreamPosition();
+ throw e;
+ }
}
public int read() throws IOException {
diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
index 6803f634762..e8f4a5d05b3 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
@@ -472,6 +472,14 @@ public class TIFFIFD extends TIFFDirectory {
// Read tag number, value type, and value count.
int tagNumber = stream.readUnsignedShort();
int type = stream.readUnsignedShort();
+ int sizeOfType;
+ try {
+ sizeOfType = TIFFTag.getSizeOfType(type);
+ } catch (IllegalArgumentException ignored) {
+ // Continue with the next IFD entry.
+ stream.skipBytes(4);
+ continue;
+ }
int count = (int)stream.readUnsignedInt();
// Get the associated TIFFTag.
@@ -510,14 +518,14 @@ public class TIFFIFD extends TIFFDirectory {
}
}
- int size = count*TIFFTag.getSizeOfType(type);
+ int size = count*sizeOfType;
if (size > 4 || tag.isIFDPointer()) {
// The IFD entry value is a pointer to the actual field value.
long offset = stream.readUnsignedInt();
// Check whether the the field value is within the stream.
if (haveStreamLength && offset + size > streamLength) {
- throw new IIOException("Field data is past end-of-stream");
+ continue;
}
// Add a TIFFIFDEntry as a placeholder. This avoids a mark,
diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
index 08c1f0ecb9a..6a90e0677c9 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
@@ -205,6 +205,10 @@ public class TIFFImageWriter extends ImageWriter {
// Next available space.
private long nextSpace = 0L;
+ private long prevStreamPosition;
+ private long prevHeaderPosition;
+ private long prevNextSpace;
+
// Whether a sequence is being written.
private boolean isWritingSequence = false;
private boolean isInsertingEmpty = false;
@@ -2300,7 +2304,14 @@ public class TIFFImageWriter extends ImageWriter {
public void write(IIOMetadata sm,
IIOImage iioimage,
ImageWriteParam p) throws IOException {
+ if (stream == null) {
+ throw new IllegalStateException("output == null!");
+ }
+ markPositions();
write(sm, iioimage, p, true, true);
+ if (abortRequested()) {
+ resetPositions();
+ }
}
private void writeHeader() throws IOException {
@@ -2333,7 +2344,7 @@ public class TIFFImageWriter extends ImageWriter {
throw new IllegalStateException("output == null!");
}
if (iioimage == null) {
- throw new NullPointerException("image == null!");
+ throw new IllegalArgumentException("image == null!");
}
if(iioimage.hasRaster() && !canWriteRasters()) {
throw new UnsupportedOperationException
@@ -2767,7 +2778,7 @@ public class TIFFImageWriter extends ImageWriter {
throw new IllegalStateException("Output not set!");
}
if (image == null) {
- throw new NullPointerException("image == null!");
+ throw new IllegalArgumentException("image == null!");
}
// Locate the position of the old IFD (ifd) and the location
@@ -2779,9 +2790,16 @@ public class TIFFImageWriter extends ImageWriter {
// imageIndex is < -1 or is too big thereby satisfying the spec.
locateIFD(imageIndex, ifdpos, ifd);
+ markPositions();
+
// Seek to the position containing the pointer to the old IFD.
stream.seek(ifdpos[0]);
+ // Save the previous pointer value in case of abort.
+ stream.mark();
+ long prevPointerValue = stream.readUnsignedInt();
+ stream.reset();
+
// Update next space pointer in anticipation of next write.
if(ifdpos[0] + 4 > nextSpace) {
nextSpace = ifdpos[0] + 4;
@@ -2805,6 +2823,12 @@ public class TIFFImageWriter extends ImageWriter {
// Update the new IFD to point to the old IFD.
stream.writeInt((int)ifd[0]);
// Don't need to update nextSpace here as already done in write().
+
+ if (abortRequested()) {
+ stream.seek(ifdpos[0]);
+ stream.writeInt((int)prevPointerValue);
+ resetPositions();
+ }
}
// ----- BEGIN insert/writeEmpty methods -----
@@ -2834,7 +2858,7 @@ public class TIFFImageWriter extends ImageWriter {
}
if(imageType == null) {
- throw new NullPointerException("imageType == null!");
+ throw new IllegalArgumentException("imageType == null!");
}
if(width < 1 || height < 1) {
@@ -2891,6 +2915,10 @@ public class TIFFImageWriter extends ImageWriter {
IIOMetadata imageMetadata,
List extends BufferedImage> thumbnails,
ImageWriteParam param) throws IOException {
+ if (stream == null) {
+ throw new IllegalStateException("output == null!");
+ }
+
checkParamsEmpty(imageType, width, height, thumbnails);
this.isWritingEmpty = true;
@@ -2901,8 +2929,12 @@ public class TIFFImageWriter extends ImageWriter {
0, 0, emptySM.getWidth(), emptySM.getHeight(),
emptySM, imageType.getColorModel());
+ markPositions();
write(streamMetadata, new IIOImage(emptyImage, null, imageMetadata),
param, true, false);
+ if (abortRequested()) {
+ resetPositions();
+ }
}
public void endInsertEmpty() throws IOException {
@@ -3015,7 +3047,7 @@ public class TIFFImageWriter extends ImageWriter {
throw new IllegalStateException("Output not set!");
}
if (region == null) {
- throw new NullPointerException("region == null!");
+ throw new IllegalArgumentException("region == null!");
}
if (region.getWidth() < 1) {
throw new IllegalArgumentException("region.getWidth() < 1!");
@@ -3200,7 +3232,7 @@ public class TIFFImageWriter extends ImageWriter {
}
if (image == null) {
- throw new NullPointerException("image == null!");
+ throw new IllegalArgumentException("image == null!");
}
if (!inReplacePixelsNest) {
@@ -3559,6 +3591,20 @@ public class TIFFImageWriter extends ImageWriter {
// ----- END replacePixels methods -----
+ // Save stream positions for use when aborted.
+ private void markPositions() throws IOException {
+ prevStreamPosition = stream.getStreamPosition();
+ prevHeaderPosition = headerPosition;
+ prevNextSpace = nextSpace;
+ }
+
+ // Reset to positions saved by markPositions().
+ private void resetPositions() throws IOException {
+ stream.seek(prevStreamPosition);
+ headerPosition = prevHeaderPosition;
+ nextSpace = prevNextSpace;
+ }
+
public void reset() {
super.reset();
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
index 8d0003cc987..6ff1ccde6b0 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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,10 +25,11 @@
package com.sun.media.sound;
+import java.util.Objects;
+
import javax.sound.midi.MidiDevice;
import javax.sound.midi.spi.MidiDeviceProvider;
-
/**
* Super class for MIDI input or output device provider.
*
@@ -127,7 +128,8 @@ public abstract class AbstractMidiDeviceProvider extends MidiDeviceProvider {
}
@Override
- public final MidiDevice getDevice(MidiDevice.Info info) {
+ public final MidiDevice getDevice(final MidiDevice.Info info) {
+ Objects.requireNonNull(info);
if (info instanceof Info) {
readDeviceInfos();
MidiDevice[] devices = getDeviceCache();
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
index 32fc90ffbb7..30c49810771 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, 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
@@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package com.sun.media.sound;
import java.io.BufferedReader;
@@ -32,6 +33,8 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
+import java.util.Objects;
+
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.Soundbank;
import javax.sound.midi.spi.SoundbankReader;
@@ -112,6 +115,7 @@ public final class JARSoundbankReader extends SoundbankReader {
public Soundbank getSoundbank(InputStream stream)
throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(stream);
return null;
}
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
index fa5bfa1afbf..32ca9ff5331 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
@@ -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
@@ -25,6 +25,8 @@
package com.sun.media.sound;
+import java.util.Objects;
+
import javax.sound.midi.MidiDevice;
import javax.sound.midi.spi.MidiDeviceProvider;
@@ -42,6 +44,7 @@ public final class RealTimeSequencerProvider extends MidiDeviceProvider {
@Override
public MidiDevice getDevice(final MidiDevice.Info info) {
+ Objects.requireNonNull(info);
if (RealTimeSequencer.info.equals(info)) {
return new RealTimeSequencer();
}
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java
index 89d85362539..e4bc1a7e342 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.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
@@ -25,6 +25,8 @@
package com.sun.media.sound;
+import java.util.Objects;
+
import javax.sound.midi.MidiDevice;
import javax.sound.midi.spi.MidiDeviceProvider;
@@ -42,6 +44,7 @@ public final class SoftProvider extends MidiDeviceProvider {
@Override
public MidiDevice getDevice(final MidiDevice.Info info) {
+ Objects.requireNonNull(info);
if (SoftSynthesizer.info.equals(info)) {
return new SoftSynthesizer();
}
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
index f03921e72df..cc75e40e251 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -25,21 +25,22 @@
package com.sun.media.sound;
-import java.io.DataOutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
-import java.io.SequenceInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.SequenceInputStream;
+import java.util.Objects;
import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.MidiEvent;
import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
import javax.sound.midi.Sequence;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.SysexMessage;
@@ -115,24 +116,16 @@ public final class StandardMidiFileWriter extends MidiFileWriter {
return typesArray;
}
- public boolean isFileTypeSupported(int type) {
- for(int i=0; i= 0) ? columns : 0;
}
@@ -297,12 +297,31 @@ public class TextField extends TextComponent {
* @see java.awt.TextComponent#getText
*/
public void setText(String t) {
- super.setText(t);
+ super.setText(replaceEOL(t));
// This could change the preferred size of the Component.
invalidateIfValid();
}
+ /**
+ * Replaces EOL characters from the text variable with a space character.
+ * @param text the new text.
+ * @return Returns text after replacing EOL characters.
+ */
+ private static String replaceEOL(String text) {
+ if (text == null) {
+ return text;
+ }
+ String[] strEOLs = {System.lineSeparator(), "\n"};
+ for (String eol : strEOLs) {
+ if (text.contains(eol)) {
+ text = text.replace(eol, " ");
+ }
+ }
+ return text;
+ }
+
+
/**
* Indicates whether or not this text field has a
* character set for echoing.
@@ -704,6 +723,7 @@ public class TextField extends TextComponent {
{
// HeadlessException will be thrown by TextComponent's readObject
s.defaultReadObject();
+ text = replaceEOL(text);
// Make sure the state we just read in for columns has legal values
if (columns < 0) {
diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
index 7beea7b77a6..b56975ba15b 100644
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
@@ -564,9 +564,12 @@ public final class ImageIO {
if (stream != null) {
stream.mark();
}
- canDecode = spi.canDecodeInput(input);
- if (stream != null) {
- stream.reset();
+ try {
+ canDecode = spi.canDecodeInput(input);
+ } finally {
+ if (stream != null) {
+ stream.reset();
+ }
}
return canDecode;
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
index aa8d46b0360..7a58b1a728b 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -35,6 +35,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.Properties;
import java.util.Set;
@@ -179,10 +180,12 @@ public class MidiSystem {
* due to resource restrictions
* @throws IllegalArgumentException if the info object does not represent a
* MIDI device installed on the system
+ * @throws NullPointerException if {@code info} is {@code null}
* @see #getMidiDeviceInfo
*/
public static MidiDevice getMidiDevice(final MidiDevice.Info info)
throws MidiUnavailableException {
+ Objects.requireNonNull(info);
for (final MidiDeviceProvider provider : getMidiDeviceProviders()) {
if (provider.isDeviceSupported(info)) {
return provider.getDevice(info);
@@ -447,11 +450,13 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the stream does not point to valid
* MIDI soundbank data recognized by the system
* @throws IOException if an I/O error occurred when loading the soundbank
+ * @throws NullPointerException if {@code stream} is {@code null}
* @see InputStream#markSupported
* @see InputStream#mark
*/
- public static Soundbank getSoundbank(InputStream stream)
- throws InvalidMidiDataException, IOException {
+ public static Soundbank getSoundbank(final InputStream stream)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(stream);
SoundbankReader sp = null;
Soundbank s = null;
@@ -479,9 +484,11 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* soundbank data recognized by the system
* @throws IOException if an I/O error occurred when loading the soundbank
+ * @throws NullPointerException if {@code url} is {@code null}
*/
- public static Soundbank getSoundbank(URL url)
- throws InvalidMidiDataException, IOException {
+ public static Soundbank getSoundbank(final URL url)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(url);
SoundbankReader sp = null;
Soundbank s = null;
@@ -509,9 +516,11 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the {@code File} does not point to
* valid MIDI soundbank data recognized by the system
* @throws IOException if an I/O error occurred when loading the soundbank
+ * @throws NullPointerException if {@code file} is {@code null}
*/
- public static Soundbank getSoundbank(File file)
- throws InvalidMidiDataException, IOException {
+ public static Soundbank getSoundbank(final File file)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(file);
SoundbankReader sp = null;
Soundbank s = null;
@@ -556,13 +565,15 @@ public class MidiSystem {
* MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs while accessing the
* stream
+ * @throws NullPointerException if {@code stream} is {@code null}
* @see #getMidiFileFormat(URL)
* @see #getMidiFileFormat(File)
* @see InputStream#markSupported
* @see InputStream#mark
*/
- public static MidiFileFormat getMidiFileFormat(InputStream stream)
- throws InvalidMidiDataException, IOException {
+ public static MidiFileFormat getMidiFileFormat(final InputStream stream)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(stream);
List providers = getMidiFileReaders();
MidiFileFormat format = null;
@@ -602,11 +613,13 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* file data recognized by the system
* @throws IOException if an I/O exception occurs while accessing the URL
+ * @throws NullPointerException if {@code url} is {@code null}
* @see #getMidiFileFormat(InputStream)
* @see #getMidiFileFormat(File)
*/
- public static MidiFileFormat getMidiFileFormat(URL url)
- throws InvalidMidiDataException, IOException {
+ public static MidiFileFormat getMidiFileFormat(final URL url)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(url);
List providers = getMidiFileReaders();
MidiFileFormat format = null;
@@ -646,11 +659,13 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the {@code File} does not point to
* valid MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs while accessing the file
+ * @throws NullPointerException if {@code file} is {@code null}
* @see #getMidiFileFormat(InputStream)
* @see #getMidiFileFormat(URL)
*/
- public static MidiFileFormat getMidiFileFormat(File file)
- throws InvalidMidiDataException, IOException {
+ public static MidiFileFormat getMidiFileFormat(final File file)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(file);
List providers = getMidiFileReaders();
MidiFileFormat format = null;
@@ -699,11 +714,13 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the stream does not point to valid
* MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs while accessing the stream
+ * @throws NullPointerException if {@code stream} is {@code null}
* @see InputStream#markSupported
* @see InputStream#mark
*/
- public static Sequence getSequence(InputStream stream)
- throws InvalidMidiDataException, IOException {
+ public static Sequence getSequence(final InputStream stream)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(stream);
List providers = getMidiFileReaders();
Sequence sequence = null;
@@ -743,9 +760,11 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* file data recognized by the system
* @throws IOException if an I/O exception occurs while accessing the URL
+ * @throws NullPointerException if {@code url} is {@code null}
*/
- public static Sequence getSequence(URL url)
- throws InvalidMidiDataException, IOException {
+ public static Sequence getSequence(final URL url)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(url);
List providers = getMidiFileReaders();
Sequence sequence = null;
@@ -787,9 +806,11 @@ public class MidiSystem {
* @throws InvalidMidiDataException if the File does not point to valid MIDI
* file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code file} is {@code null}
*/
- public static Sequence getSequence(File file)
- throws InvalidMidiDataException, IOException {
+ public static Sequence getSequence(final File file)
+ throws InvalidMidiDataException, IOException {
+ Objects.requireNonNull(file);
List providers = getMidiFileReaders();
Sequence sequence = null;
@@ -870,8 +891,10 @@ public class MidiSystem {
* @param sequence the sequence for which MIDI file type support is queried
* @return the set of unique supported file types. If no file types are
* supported, returns an array of length 0.
+ * @throws NullPointerException if {@code sequence} is {@code null}
*/
- public static int[] getMidiFileTypes(Sequence sequence) {
+ public static int[] getMidiFileTypes(final Sequence sequence) {
+ Objects.requireNonNull(sequence);
List providers = getMidiFileWriters();
Set allTypes = new HashSet<>();
@@ -903,8 +926,11 @@ public class MidiSystem {
* @param sequence the sequence for which file writing support is queried
* @return {@code true} if the file type is supported for this sequence,
* otherwise {@code false}
+ * @throws NullPointerException if {@code sequence} is {@code null}
*/
- public static boolean isFileTypeSupported(int fileType, Sequence sequence) {
+ public static boolean isFileTypeSupported(final int fileType,
+ final Sequence sequence) {
+ Objects.requireNonNull(sequence);
List providers = getMidiFileWriters();
@@ -929,10 +955,15 @@ public class MidiSystem {
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if the file format is not supported by
* the system
+ * @throws NullPointerException if {@code in} or {@code out} are
+ * {@code null}
* @see #isFileTypeSupported(int, Sequence)
* @see #getMidiFileTypes(Sequence)
*/
- public static int write(Sequence in, int fileType, OutputStream out) throws IOException {
+ public static int write(final Sequence in, final int fileType,
+ final OutputStream out) throws IOException {
+ Objects.requireNonNull(in);
+ Objects.requireNonNull(out);
List providers = getMidiFileWriters();
//$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
@@ -963,10 +994,15 @@ public class MidiSystem {
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if the file type is not supported by the
* system
+ * @throws NullPointerException if {@code in} or {@code out} are
+ * {@code null}
* @see #isFileTypeSupported(int, Sequence)
* @see #getMidiFileTypes(Sequence)
*/
- public static int write(Sequence in, int type, File out) throws IOException {
+ public static int write(final Sequence in, final int type, final File out)
+ throws IOException {
+ Objects.requireNonNull(in);
+ Objects.requireNonNull(out);
List providers = getMidiFileWriters();
//$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
index 97c9d92b7f0..4f820b497d7 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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.sound.midi.spi;
import java.util.Arrays;
+import java.util.Objects;
import javax.sound.midi.MidiDevice;
@@ -46,8 +47,10 @@ public abstract class MidiDeviceProvider {
* is queried
* @return {@code true} if the specified device is supported, otherwise
* {@code false}
+ * @throws NullPointerException if {@code info} is {@code null}
*/
public boolean isDeviceSupported(final MidiDevice.Info info) {
+ Objects.requireNonNull(info);
return Arrays.asList(getDeviceInfo()).contains(info);
}
@@ -67,6 +70,7 @@ public abstract class MidiDeviceProvider {
* @throws IllegalArgumentException if the info object specified does not
* match the info object for a device supported by this
* {@code MidiDeviceProvider}
+ * @throws NullPointerException if {@code info} is {@code null}
*/
public abstract MidiDevice getDevice(MidiDevice.Info info);
}
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
index bbdca9e97bb..f1c3b6f6ff5 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -60,6 +60,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the stream does not point to valid
* MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code stream} is {@code null}
* @see InputStream#markSupported
* @see InputStream#mark
*/
@@ -76,6 +77,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code url} is {@code null}
*/
public abstract MidiFileFormat getMidiFileFormat(URL url)
throws InvalidMidiDataException, IOException;
@@ -90,6 +92,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the {@code File} does not point to
* valid MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code file} is {@code null}
*/
public abstract MidiFileFormat getMidiFileFormat(File file)
throws InvalidMidiDataException, IOException;
@@ -110,6 +113,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the stream does not point to valid
* MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code stream} is {@code null}
* @see InputStream#markSupported
* @see InputStream#mark
*/
@@ -126,6 +130,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code url} is {@code null}
*/
public abstract Sequence getSequence(URL url)
throws InvalidMidiDataException, IOException;
@@ -141,6 +146,7 @@ public abstract class MidiFileReader {
* @throws InvalidMidiDataException if the {@code File} does not point to
* valid MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs
+ * @throws NullPointerException if {@code file} is {@code null}
*/
public abstract Sequence getSequence(File file)
throws InvalidMidiDataException, IOException;
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
index a1800f7f701..9a3fdcbc62e 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -58,6 +58,7 @@ public abstract class MidiFileWriter {
* queried
* @return array of file types. If no file types are supported, returns an
* array of length 0.
+ * @throws NullPointerException if {@code sequence} is {@code null}
*/
public abstract int[] getMidiFileTypes(Sequence sequence);
@@ -88,6 +89,7 @@ public abstract class MidiFileWriter {
* @param sequence the sequence for which file writing support is queried
* @return {@code true} if the file type is supported for this sequence,
* otherwise {@code false}
+ * @throws NullPointerException if {@code sequence} is {@code null}
*/
public boolean isFileTypeSupported(int fileType, Sequence sequence) {
@@ -111,6 +113,8 @@ public abstract class MidiFileWriter {
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if the file type is not supported by
* this file writer
+ * @throws NullPointerException if {@code in} or {@code out} are
+ * {@code null}
* @see #isFileTypeSupported(int, Sequence)
* @see #getMidiFileTypes(Sequence)
*/
@@ -129,6 +133,8 @@ public abstract class MidiFileWriter {
* @throws IOException if an I/O exception occurs
* @throws IllegalArgumentException if the file type is not supported by
* this file writer
+ * @throws NullPointerException if {@code in} or {@code out} are
+ * {@code null}
* @see #isFileTypeSupported(int, Sequence)
* @see #getMidiFileTypes(Sequence)
*/
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
index 501c18b6ad5..8690b0d18ed 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 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
@@ -52,6 +52,7 @@ public abstract class SoundbankReader {
* @throws InvalidMidiDataException if the URL does not point to valid MIDI
* soundbank data recognized by this soundbank reader
* @throws IOException if an I/O error occurs
+ * @throws NullPointerException if {@code url} is {@code null}
*/
public abstract Soundbank getSoundbank(URL url)
throws InvalidMidiDataException, IOException;
@@ -64,6 +65,7 @@ public abstract class SoundbankReader {
* @throws InvalidMidiDataException if the stream does not point to valid
* MIDI soundbank data recognized by this soundbank reader
* @throws IOException if an I/O error occurs
+ * @throws NullPointerException if {@code stream} is {@code null}
*/
public abstract Soundbank getSoundbank(InputStream stream)
throws InvalidMidiDataException, IOException;
@@ -76,6 +78,7 @@ public abstract class SoundbankReader {
* @throws InvalidMidiDataException if the file does not point to valid MIDI
* soundbank data recognized by this soundbank reader
* @throws IOException if an I/O error occurs
+ * @throws NullPointerException if {@code file} is {@code null}
*/
public abstract Soundbank getSoundbank(File file)
throws InvalidMidiDataException, IOException;
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
index 3276d534a48..b6fa1b7bd81 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
@@ -618,6 +618,7 @@ public abstract class JComponent extends Container implements Serializable,
* @return the {@code ComponentUI} object that renders this component
* @since 1.9
*/
+ @Transient
public ComponentUI getUI() {
return ui;
}
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
index 54cd7c037d4..bbc35bf9c1d 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
@@ -663,7 +663,9 @@ class UnixFileSystemView extends FileSystemView {
if(newFolder.exists()) {
throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
} else {
- newFolder.mkdirs();
+ if(!newFolder.mkdirs()) {
+ throw new IOException(newFolder.getAbsolutePath());
+ }
}
return newFolder;
@@ -773,7 +775,9 @@ class WindowsFileSystemView extends FileSystemView {
if(newFolder.exists()) {
throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
} else {
- newFolder.mkdirs();
+ if(!newFolder.mkdirs()) {
+ throw new IOException(newFolder.getAbsolutePath());
+ }
}
return newFolder;
@@ -842,9 +846,10 @@ class GenericFileSystemView extends FileSystemView {
if(newFolder.exists()) {
throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
} else {
- newFolder.mkdirs();
+ if(!newFolder.mkdirs()) {
+ throw new IOException(newFolder.getAbsolutePath());
+ }
}
-
return newFolder;
}
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
index 2b87618abd9..b965ccfcbc0 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
@@ -36,6 +36,7 @@ import javax.swing.tree.TreeNode;
import sun.font.BidiUtils;
import sun.swing.SwingUtilities2;
+import sun.swing.text.UndoableEditLockSupport;
/**
* An implementation of the document interface to serve as a
@@ -275,6 +276,11 @@ public abstract class AbstractDocument implements Document, Serializable {
* @see EventListenerList
*/
protected void fireUndoableEditUpdate(UndoableEditEvent e) {
+ if (e.getEdit() instanceof DefaultDocumentEvent) {
+ e = new UndoableEditEvent(e.getSource(),
+ new DefaultDocumentEventUndoableWrapper(
+ (DefaultDocumentEvent)e.getEdit()));
+ }
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
@@ -2952,6 +2958,88 @@ public abstract class AbstractDocument implements Document, Serializable {
}
+ static class DefaultDocumentEventUndoableWrapper implements
+ UndoableEdit, UndoableEditLockSupport
+ {
+ final DefaultDocumentEvent dde;
+ public DefaultDocumentEventUndoableWrapper(DefaultDocumentEvent dde) {
+ this.dde = dde;
+ }
+
+ @Override
+ public void undo() throws CannotUndoException {
+ dde.undo();
+ }
+
+ @Override
+ public boolean canUndo() {
+ return dde.canUndo();
+ }
+
+ @Override
+ public void redo() throws CannotRedoException {
+ dde.redo();
+ }
+
+ @Override
+ public boolean canRedo() {
+ return dde.canRedo();
+ }
+
+ @Override
+ public void die() {
+ dde.die();
+ }
+
+ @Override
+ public boolean addEdit(UndoableEdit anEdit) {
+ return dde.addEdit(anEdit);
+ }
+
+ @Override
+ public boolean replaceEdit(UndoableEdit anEdit) {
+ return dde.replaceEdit(anEdit);
+ }
+
+ @Override
+ public boolean isSignificant() {
+ return dde.isSignificant();
+ }
+
+ @Override
+ public String getPresentationName() {
+ return dde.getPresentationName();
+ }
+
+ @Override
+ public String getUndoPresentationName() {
+ return dde.getUndoPresentationName();
+ }
+
+ @Override
+ public String getRedoPresentationName() {
+ return dde.getRedoPresentationName();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.9
+ */
+ @Override
+ public void lockEdit() {
+ ((AbstractDocument)dde.getDocument()).writeLock();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.9
+ */
+ @Override
+ public void unlockEdit() {
+ ((AbstractDocument)dde.getDocument()).writeUnlock();
+ }
+ }
+
/**
* This event used when firing document changes while Undo/Redo
* operations. It just wraps DefaultDocumentEvent and delegates
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java b/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
index 782dd3b3356..cb85826e611 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
@@ -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
@@ -28,6 +28,7 @@ package javax.swing.undo;
import javax.swing.event.*;
import javax.swing.UIManager;
import java.util.*;
+import sun.swing.text.UndoableEditLockSupport;
/**
* {@code UndoManager} manages a list of {@code UndoableEdits},
@@ -134,6 +135,11 @@ import java.util.*;
*/
@SuppressWarnings("serial") // Same-version serialization only
public class UndoManager extends CompoundEdit implements UndoableEditListener {
+ private enum Action {
+ UNDO,
+ REDO,
+ ANY
+ }
int indexOfNextAdd;
int limit;
@@ -369,13 +375,8 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
* @throws CannotRedoException if one of the edits throws
* CannotRedoException
*/
- public synchronized void undoOrRedo() throws CannotRedoException,
- CannotUndoException {
- if (indexOfNextAdd == edits.size()) {
- undo();
- } else {
- redo();
- }
+ public void undoOrRedo() throws CannotRedoException, CannotUndoException {
+ tryUndoOrRedo(Action.ANY);
}
/**
@@ -407,16 +408,8 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
* @see #canUndo
* @see #editToBeUndone
*/
- public synchronized void undo() throws CannotUndoException {
- if (inProgress) {
- UndoableEdit edit = editToBeUndone();
- if (edit == null) {
- throw new CannotUndoException();
- }
- undoTo(edit);
- } else {
- super.undo();
- }
+ public void undo() throws CannotUndoException {
+ tryUndoOrRedo(Action.UNDO);
}
/**
@@ -452,16 +445,90 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
* @see #canRedo
* @see #editToBeRedone
*/
- public synchronized void redo() throws CannotRedoException {
- if (inProgress) {
- UndoableEdit edit = editToBeRedone();
- if (edit == null) {
- throw new CannotRedoException();
+ public void redo() throws CannotRedoException {
+ tryUndoOrRedo(Action.REDO);
+ }
+
+ private void tryUndoOrRedo(Action action) {
+ UndoableEditLockSupport lockSupport = null;
+ boolean undo;
+ synchronized (this) {
+ if (action == Action.ANY) {
+ undo = indexOfNextAdd == edits.size();
+ } else {
+ undo = action == Action.UNDO;
+ }
+ if (inProgress) {
+ UndoableEdit edit = undo ? editToBeUndone() : editToBeRedone();
+ if (edit == null) {
+ throw undo ? new CannotUndoException() :
+ new CannotRedoException();
+ }
+ lockSupport = getEditLockSupport(edit);
+ if (lockSupport == null) {
+ if (undo) {
+ undoTo(edit);
+ } else {
+ redoTo(edit);
+ }
+ return;
+ }
+ } else {
+ if (undo) {
+ super.undo();
+ } else {
+ super.redo();
+ }
+ return;
}
- redoTo(edit);
- } else {
- super.redo();
}
+ // the edit synchronization is required
+ while (true) {
+ lockSupport.lockEdit();
+ UndoableEditLockSupport editLockSupport = null;
+ try {
+ synchronized (this) {
+ if (action == Action.ANY) {
+ undo = indexOfNextAdd == edits.size();
+ }
+ if (inProgress) {
+ UndoableEdit edit = undo ? editToBeUndone() :
+ editToBeRedone();
+ if (edit == null) {
+ throw undo ? new CannotUndoException() :
+ new CannotRedoException();
+ }
+ editLockSupport = getEditLockSupport(edit);
+ if (editLockSupport == null ||
+ editLockSupport == lockSupport) {
+ if (undo) {
+ undoTo(edit);
+ } else {
+ redoTo(edit);
+ }
+ return;
+ }
+ } else {
+ if (undo) {
+ super.undo();
+ } else {
+ super.redo();
+ }
+ return;
+ }
+ }
+ } finally {
+ if (lockSupport != null) {
+ lockSupport.unlockEdit();
+ }
+ lockSupport = editLockSupport;
+ }
+ }
+ }
+
+ private UndoableEditLockSupport getEditLockSupport(UndoableEdit anEdit) {
+ return anEdit instanceof UndoableEditLockSupport ?
+ (UndoableEditLockSupport)anEdit : null;
}
/**
diff --git a/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java b/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
index 00c8911f696..1ee5c4019f1 100644
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
@@ -70,6 +70,10 @@ public class SunVolatileImage extends VolatileImage
{
this.comp = comp;
this.graphicsConfig = graphicsConfig;
+ if (width <= 0 || height <= 0) {
+ throw new IllegalArgumentException("Width (" + width + ")" +
+ " and height (" + height + ") cannot be <= 0");
+ }
this.width = width;
this.height = height;
this.forcedAccelSurfaceType = accType;
diff --git a/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java b/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
index 06abf9de163..69f1d4babc2 100644
--- a/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
+++ b/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
@@ -445,13 +445,19 @@ public class StandardGlyphVector extends GlyphVector {
}
public void setGlyphPosition(int ix, Point2D pos) {
+ if (ix < 0 || ix > glyphs.length) {
+ throw new IndexOutOfBoundsException("ix = " + ix);
+ }
+
initPositions();
int ix2 = ix << 1;
positions[ix2] = (float)pos.getX();
positions[ix2 + 1] = (float)pos.getY();
- clearCaches(ix);
+ if (ix < glyphs.length) {
+ clearCaches(ix);
+ }
addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
}
diff --git a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
index c4893b6dd60..7668b6572a8 100644
--- a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
+++ b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
@@ -176,6 +176,13 @@ public class TrueTypeFont extends FileFont {
private String localeFamilyName;
private String localeFullName;
+ public TrueTypeFont(String platname, Object nativeNames, int fIndex,
+ boolean javaRasterizer)
+ throws FontFormatException
+ {
+ this(platname, nativeNames, fIndex, javaRasterizer, true);
+ }
+
/**
* - does basic verification of the file
* - reads the header table for this font (within a collection)
@@ -186,14 +193,17 @@ public class TrueTypeFont extends FileFont {
* or fails verification, or there's no usable cmap
*/
public TrueTypeFont(String platname, Object nativeNames, int fIndex,
- boolean javaRasterizer)
+ boolean javaRasterizer, boolean useFilePool)
throws FontFormatException {
super(platname, nativeNames);
useJavaRasterizer = javaRasterizer;
fontRank = Font2D.TTF_RANK;
try {
- verify();
+ verify(useFilePool);
init(fIndex);
+ if (!useFilePool) {
+ close();
+ }
} catch (Throwable t) {
close();
if (t instanceof FontFormatException) {
@@ -280,6 +290,10 @@ public class TrueTypeFont extends FileFont {
}
+ private synchronized FileChannel open() throws FontFormatException {
+ return open(true);
+ }
+
/* This is intended to be called, and the returned value used,
* from within a block synchronized on this font object.
* ie the channel returned may be nulled out at any time by "close()"
@@ -287,7 +301,8 @@ public class TrueTypeFont extends FileFont {
* Deadlock warning: FontManager.addToPool(..) acquires a global lock,
* which means nested locks may be in effect.
*/
- private synchronized FileChannel open() throws FontFormatException {
+ private synchronized FileChannel open(boolean usePool)
+ throws FontFormatException {
if (disposerRecord.channel == null) {
if (FontUtilities.isLogging()) {
FontUtilities.getLogger().info("open TTF: " + platName);
@@ -306,9 +321,11 @@ public class TrueTypeFont extends FileFont {
});
disposerRecord.channel = raf.getChannel();
fileSize = (int)disposerRecord.channel.size();
- FontManager fm = FontManagerFactory.getInstance();
- if (fm instanceof SunFontManager) {
- ((SunFontManager) fm).addToPool(this);
+ if (usePool) {
+ FontManager fm = FontManagerFactory.getInstance();
+ if (fm instanceof SunFontManager) {
+ ((SunFontManager) fm).addToPool(this);
+ }
}
} catch (NullPointerException e) {
close();
@@ -492,8 +509,8 @@ public class TrueTypeFont extends FileFont {
}
}
- private void verify() throws FontFormatException {
- open();
+ private void verify(boolean usePool) throws FontFormatException {
+ open(usePool);
}
/* sizes, in bytes, of TT/TTC header records */
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
index bc4bc54d0d5..e518c4d2261 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
@@ -166,18 +166,31 @@ public final class ArrayCache implements MarlinConst {
* @return new array size
*/
public static int getNewSize(final int curSize, final int needSize) {
+ // check if needSize is negative or integer overflow:
+ if (needSize < 0) {
+ // hard overflow failure - we can't even accommodate
+ // new items without overflowing
+ throw new ArrayIndexOutOfBoundsException(
+ "array exceeds maximum capacity !");
+ }
+ assert curSize >= 0;
final int initial = (curSize & MASK_CLR_1);
int size;
if (initial > THRESHOLD_ARRAY_SIZE) {
size = initial + (initial >> 1); // x(3/2)
} else {
- size = (initial) << 1; // x2
+ size = (initial << 1); // x2
}
// ensure the new size is >= needed size:
if (size < needSize) {
- // align to 4096:
+ // align to 4096 (may overflow):
size = ((needSize >> 12) + 1) << 12;
}
+ // check integer overflow:
+ if (size < 0) {
+ // resize to maximum capacity:
+ size = Integer.MAX_VALUE;
+ }
return size;
}
@@ -188,26 +201,29 @@ public final class ArrayCache implements MarlinConst {
* @return new array size
*/
public static long getNewLargeSize(final long curSize, final long needSize) {
+ // check if needSize is negative or integer overflow:
+ if ((needSize >> 31L) != 0L) {
+ // hard overflow failure - we can't even accommodate
+ // new items without overflowing
+ throw new ArrayIndexOutOfBoundsException(
+ "array exceeds maximum capacity !");
+ }
+ assert curSize >= 0L;
long size;
if (curSize > THRESHOLD_HUGE_ARRAY_SIZE) {
size = curSize + (curSize >> 2L); // x(5/4)
} else if (curSize > THRESHOLD_LARGE_ARRAY_SIZE) {
size = curSize + (curSize >> 1L); // x(3/2)
} else {
- size = curSize << 1L; // x2
+ size = (curSize << 1L); // x2
}
// ensure the new size is >= needed size:
if (size < needSize) {
// align to 4096:
- size = ((needSize >> 12) + 1) << 12;
+ size = ((needSize >> 12L) + 1L) << 12L;
}
- if (size >= Integer.MAX_VALUE) {
- if (curSize >= Integer.MAX_VALUE) {
- // hard overflow failure - we can't even accommodate
- // new items without overflowing
- throw new ArrayIndexOutOfBoundsException(
- "array exceeds maximum capacity !");
- }
+ // check integer overflow:
+ if (size > Integer.MAX_VALUE) {
// resize to maximum capacity:
size = Integer.MAX_VALUE;
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
index cd6ebee89e8..226a3d2e30d 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
@@ -74,7 +74,7 @@ final class ByteArrayCache implements MarlinConst {
void putDirtyArray(final byte[] array, final int length) {
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
@@ -98,7 +98,7 @@ final class ByteArrayCache implements MarlinConst {
{
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
index a068ad80fbc..06d7f351e28 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
@@ -75,7 +75,7 @@ final class FloatArrayCache implements MarlinConst {
void putDirtyArray(final float[] array, final int length) {
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
@@ -99,7 +99,7 @@ final class FloatArrayCache implements MarlinConst {
{
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
index d1ffc04b786..df6af52438c 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
@@ -24,8 +24,8 @@
*/
package sun.java2d.marlin;
-import sun.misc.DoubleConsts;
-import sun.misc.FloatConsts;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FloatConsts;
/**
* Faster Math ceil / floor routines derived from StrictMath
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
index ccd239cb534..11c5aae84f6 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
@@ -74,7 +74,7 @@ final class IntArrayCache implements MarlinConst {
void putDirtyArray(final int[] array, final int length) {
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
@@ -98,7 +98,7 @@ final class IntArrayCache implements MarlinConst {
{
if (length != arraySize) {
if (doChecks) {
- System.out.println("ArrayCache: bad length = " + length);
+ MarlinUtils.logInfo("ArrayCache: bad length = " + length);
}
return;
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
index e799504318d..72993ebfd7c 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
@@ -30,8 +30,8 @@ package sun.java2d.marlin;
*/
interface MarlinConst {
// enable Logs (logger or stdout)
- static final boolean enableLogs = false;
- // enable Logger
+ static final boolean enableLogs = MarlinProperties.isLoggingEnabled();
+ // use Logger instead of stdout
static final boolean useLogger = enableLogs && MarlinProperties.isUseLogger();
// log new RendererContext
@@ -47,9 +47,10 @@ interface MarlinConst {
static final boolean doStats = enableLogs && MarlinProperties.isDoStats();
// do monitors
// disabled to reduce byte-code size a bit...
- static final boolean doMonitors = enableLogs && false; // MarlinProperties.isDoMonitors();
+ static final boolean doMonitors = false;
+// static final boolean doMonitors = enableLogs && MarlinProperties.isDoMonitors();
// do checks
- static final boolean doChecks = false; // MarlinProperties.isDoChecks();
+ static final boolean doChecks = enableLogs && MarlinProperties.isDoChecks();
// do AA range checks: disable when algorithm / code is stable
static final boolean DO_AA_RANGE_CHECK = false;
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
index 002f16d9d5b..bbee15a13fb 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
@@ -136,6 +136,10 @@ public final class MarlinProperties {
// logging parameters
+ public static boolean isLoggingEnabled() {
+ return getBoolean("sun.java2d.renderer.log", "false");
+ }
+
public static boolean isUseLogger() {
return getBoolean("sun.java2d.renderer.useLogger", "false");
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
index d218d06f545..aeeacca57bd 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
@@ -27,12 +27,12 @@ package sun.java2d.marlin;
public final class MarlinUtils {
- // TODO: use sun.util.logging.PlatformLogger once in JDK9
- private static final java.util.logging.Logger log;
+ // Marlin logger
+ private static final sun.util.logging.PlatformLogger log;
static {
if (MarlinConst.useLogger) {
- log = java.util.logging.Logger.getLogger("sun.java2d.marlin");
+ log = sun.util.logging.PlatformLogger.getLogger("sun.java2d.marlin");
} else {
log = null;
}
@@ -53,25 +53,11 @@ public final class MarlinUtils {
public static void logException(final String msg, final Throwable th) {
if (MarlinConst.useLogger) {
-// log.warning(msg, th);
- log.log(java.util.logging.Level.WARNING, msg, th);
+ log.warning(msg, th);
} else if (MarlinConst.enableLogs) {
System.out.print("WARNING: ");
System.out.println(msg);
th.printStackTrace(System.err);
}
}
-
- // Returns the caller's class and method's name; best effort
- // if cannot infer, return the logger's name.
- static String getCallerInfo(String className) {
- String sourceClassName = null;
- String sourceMethodName = null;
-
- if (sourceClassName != null) {
- return sourceClassName + " " + sourceMethodName;
- } else {
- return "unknown";
- }
- }
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
index d4aa005eadb..f59785cd92f 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
@@ -629,6 +629,13 @@ final class Renderer implements PathConsumer2D, MarlinConst {
}
if (edgeMinY != Float.POSITIVE_INFINITY) {
+ // if context is maked as DIRTY:
+ if (rdrCtx.dirty) {
+ // may happen if an exception if thrown in the pipeline processing:
+ // clear completely buckets arrays:
+ buckets_minY = 0;
+ buckets_maxY = boundsMaxY - boundsMinY;
+ }
// clear used part
if (edgeBuckets == edgeBuckets_initial) {
// fill only used part
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
index 7af675b16b7..a767651f5d5 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
@@ -31,7 +31,6 @@ import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import static sun.java2d.marlin.ArrayCache.*;
import sun.java2d.marlin.MarlinRenderingEngine.NormalizingPathIterator;
-import static sun.java2d.marlin.MarlinUtils.getCallerInfo;
import static sun.java2d.marlin.MarlinUtils.logInfo;
/**
@@ -39,7 +38,6 @@ import static sun.java2d.marlin.MarlinUtils.logInfo;
*/
final class RendererContext implements MarlinConst {
- private static final String className = RendererContext.class.getName();
// RendererContext creation counter
private static final AtomicInteger contextCount = new AtomicInteger(1);
// RendererContext statistics
@@ -214,8 +212,7 @@ final class RendererContext implements MarlinConst {
}
if (doLogOverSize) {
- logInfo("getDirtyByteArray[oversize]: length=\t" + length
- + "\tfrom=\t" + getCallerInfo(className));
+ logInfo("getDirtyByteArray[oversize]: length=\t" + length);
}
return new byte[length];
@@ -254,7 +251,7 @@ final class RendererContext implements MarlinConst {
if (doLogWidenArray) {
logInfo("widenDirtyByteArray[" + res.length + "]: usedSize=\t"
+ usedSize + "\tlength=\t" + length + "\tneeded length=\t"
- + needSize + "\tfrom=\t" + getCallerInfo(className));
+ + needSize);
}
return res;
}
@@ -275,8 +272,7 @@ final class RendererContext implements MarlinConst {
}
if (doLogOverSize) {
- logInfo("getIntArray[oversize]: length=\t" + length + "\tfrom=\t"
- + getCallerInfo(className));
+ logInfo("getIntArray[oversize]: length=\t" + length);
}
return new int[length];
@@ -306,7 +302,7 @@ final class RendererContext implements MarlinConst {
if (doLogWidenArray) {
logInfo("widenIntArray[" + res.length + "]: usedSize=\t"
+ usedSize + "\tlength=\t" + length + "\tneeded length=\t"
- + needSize + "\tfrom=\t" + getCallerInfo(className));
+ + needSize);
}
return res;
}
@@ -338,8 +334,7 @@ final class RendererContext implements MarlinConst {
}
if (doLogOverSize) {
- logInfo("getDirtyIntArray[oversize]: length=\t" + length
- + "\tfrom=\t" + getCallerInfo(className));
+ logInfo("getDirtyIntArray[oversize]: length=\t" + length);
}
return new int[length];
@@ -369,7 +364,7 @@ final class RendererContext implements MarlinConst {
if (doLogWidenArray) {
logInfo("widenDirtyIntArray[" + res.length + "]: usedSize=\t"
+ usedSize + "\tlength=\t" + length + "\tneeded length=\t"
- + needSize + "\tfrom=\t" + getCallerInfo(className));
+ + needSize);
}
return res;
}
@@ -399,8 +394,7 @@ final class RendererContext implements MarlinConst {
}
if (doLogOverSize) {
- logInfo("getDirtyFloatArray[oversize]: length=\t" + length
- + "\tfrom=\t" + getCallerInfo(className));
+ logInfo("getDirtyFloatArray[oversize]: length=\t" + length);
}
return new float[length];
@@ -430,7 +424,7 @@ final class RendererContext implements MarlinConst {
if (doLogWidenArray) {
logInfo("widenDirtyFloatArray[" + res.length + "]: usedSize=\t"
+ usedSize + "\tlength=\t" + length + "\tneeded length=\t"
- + needSize + "\tfrom=\t" + getCallerInfo(className));
+ + needSize);
}
return res;
}
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
index 6ddb5253372..4588bf270b3 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
@@ -25,6 +25,8 @@
package sun.java2d.marlin;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -32,6 +34,7 @@ import static sun.java2d.marlin.MarlinUtils.logInfo;
import sun.java2d.marlin.stats.Histogram;
import sun.java2d.marlin.stats.Monitor;
import sun.java2d.marlin.stats.StatLong;
+import sun.awt.util.ThreadGroupUtils;
/**
* This class gathers global rendering statistics for debugging purposes only
@@ -237,22 +240,33 @@ public final class RendererStats implements MarlinConst {
private RendererStats() {
super();
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- dump();
- }
- });
+ AccessController.doPrivileged(
+ (PrivilegedAction) () -> {
+ final Thread hook = new Thread(
+ ThreadGroupUtils.getRootThreadGroup(),
+ new Runnable() {
+ @Override
+ public void run() {
+ dump();
+ }
+ },
+ "MarlinStatsHook"
+ );
+ hook.setContextClassLoader(null);
+ Runtime.getRuntime().addShutdownHook(hook);
- if (useDumpThread) {
- final Timer statTimer = new Timer("RendererStats");
- statTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- dump();
+ if (useDumpThread) {
+ final Timer statTimer = new Timer("RendererStats");
+ statTimer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ dump();
+ }
+ }, statDump, statDump);
}
- }, statDump, statDump);
- }
+ return null;
+ }
+ );
}
void dump() {
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
index 76c93494d57..1aa48411f04 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
@@ -1265,14 +1265,15 @@ final class Stroker implements PathConsumer2D, MarlinConst {
}
private void ensureSpace(final int n) {
- if (end + n > curves.length) {
+ // use substraction to avoid integer overflow:
+ if (curves.length - end < n) {
if (doStats) {
RendererContext.stats.stat_array_stroker_polystack_curves
.add(end + n);
}
curves = rdrCtx.widenDirtyFloatArray(curves, end, end + n);
}
- if (numCurves + 1 > curveTypes.length) {
+ if (curveTypes.length <= numCurves) {
if (doStats) {
RendererContext.stats.stat_array_stroker_polystack_curveTypes
.add(numCurves + 1);
diff --git a/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java b/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java
new file mode 100644
index 00000000000..43440da0dc8
--- /dev/null
+++ b/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java
@@ -0,0 +1,43 @@
+/*
+ * 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 sun.swing.text;
+
+import javax.swing.undo.UndoableEdit;
+
+/**
+ * UndoableEdit support for undo/redo actions synchronization
+ * @since 1.9
+ */
+public interface UndoableEditLockSupport extends UndoableEdit {
+ /**
+ * lock the UndoableEdit for threadsafe undo/redo
+ */
+ void lockEdit();
+
+ /**
+ * unlock the UndoableEdit
+ */
+ void unlockEdit();
+}
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
index 8c8c47593fb..3d133952d4d 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
+++ b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
@@ -67,12 +67,6 @@ FontInstanceAdapter::FontInstanceAdapter(JNIEnv *theEnv,
};
-const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
-{
- size_t ignored = 0;
- return getFontTable(tableTag, ignored);
-}
-
static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
};
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
index 8d2ee3073a0..0d8322dddbe 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
+++ b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
@@ -85,7 +85,6 @@ public:
// tables are cached with the native font scaler data
// only supports gsub, gpos, gdef, mort tables at present
- virtual const void *getFontTable(LETag tableTag) const;
virtual const void *getFontTable(LETag tableTag, size_t &len) const;
virtual void *getKernPairs() const {
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
index 422575cb165..00c6ee1fa44 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
+++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
@@ -80,15 +80,18 @@ int storeGVData(JNIEnv* env,
float scale = 1.0f/64.0f;
unsigned int* glyphs;
float* positions;
+ int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv;
+ unsigned int* indices;
+ jarray glyphArray, posArray, inxArray;
if (!init_JNI_IDs(env)) {
return 0;
}
- int initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
- jarray glyphArray =
+ initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
+ glyphArray =
(jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
- jarray posArray =
+ posArray =
(jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
if (glyphArray == NULL || posArray == NULL)
@@ -101,9 +104,9 @@ int storeGVData(JNIEnv* env,
// and re-invokes layout. I suppose this is expected to be rare
// because at least in a single threaded case there should be
// re-use of the same container, but it is a little wasteful/distateful.
- int glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
- int posArrayLen = (*env)->GetArrayLength(env, posArray);
- int maxGlyphs = glyphCount + initialCount;
+ glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
+ posArrayLen = (*env)->GetArrayLength(env, posArray);
+ maxGlyphs = glyphCount + initialCount;
if ((maxGlyphs > glyphArrayLen) ||
(maxGlyphs * 2 + 2 > posArrayLen))
{
@@ -125,7 +128,7 @@ int storeGVData(JNIEnv* env,
x += glyphPos[i].x_advance * scale;
y += glyphPos[i].y_advance * scale;
}
- int storeadv = initialCount+glyphCount;
+ storeadv = initialCount+glyphCount;
// The final slot in the positions array is important
// because when the GlyphVector is created from this
// data it determines the overall advance of the glyphvector
@@ -138,11 +141,10 @@ int storeGVData(JNIEnv* env,
(*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
(*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
putFloat(env, startPt,positions[(storeadv*2)],positions[(storeadv*2)+1] );
- jarray inxArray =
+ inxArray =
(jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
- unsigned int* indices =
+ indices =
(unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
- int prevCluster = -1;
for (i = 0; i < glyphCount; i++) {
int cluster = glyphInfo[i].cluster;
if (direction == HB_DIRECTION_LTR) {
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
index 5fe5372be2f..c2a294f91b7 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
+++ b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
@@ -258,7 +258,7 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler(
scalerInfo->fontData,
scalerInfo->fontDataLength);
if (bBuffer != NULL) {
- (*env)->CallObjectMethod(env, font2D,
+ (*env)->CallVoidMethod(env, font2D,
sunFontIDs.readFileMID, bBuffer);
error = FT_New_Memory_Face(scalerInfo->library,
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h b/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
index 2baf2d6c85e..3ac687906fa 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
@@ -172,28 +172,6 @@ public:
// Font file access
//
- /**
- * This method reads a table from the font. Note that in general,
- * it only makes sense to call this method on an LEFontInstance
- * which represents a physical font - i.e. one which has been returned by
- * getSubFont(). This is because each subfont in a composite font
- * will have different tables, and there's no way to know which subfont to access.
- *
- * Subclasses which represent composite fonts should always return NULL.
- *
- * Note that implementing this function does not allow for range checking.
- * Subclasses that desire the safety of range checking must implement the
- * variation which has a length parameter.
- *
- * @param tableTag - the four byte table tag. (e.g. 'cmap')
- *
- * @return the address of the table in memory, or NULL
- * if the table doesn't exist.
- *
- * @stable ICU 2.8
- */
- virtual const void *getFontTable(LETag tableTag) const = 0;
-
/**
* This method reads a table from the font. Note that in general,
* it only makes sense to call this method on an LEFontInstance
@@ -213,7 +191,7 @@ public:
* if the table doesn't exist.
* @internal
*/
- virtual const void* getFontTable(LETag tableTag, size_t &length) const { length=-1; return getFontTable(tableTag); } /* -1 = unknown length */
+ virtual const void* getFontTable(LETag tableTag, size_t &length) const = 0;
virtual void *getKernPairs() const = 0;
virtual void setKernPairs(void *pairs) const = 0;
diff --git a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
index f0d5c019a8d..81fe9117d04 100644
--- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
@@ -1610,6 +1610,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
int ret;
int h_samp0, h_samp1, h_samp2;
int v_samp0, v_samp1, v_samp2;
+ int cid0, cid1, cid2;
jboolean retval = JNI_FALSE;
imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
j_decompress_ptr cinfo;
@@ -1711,17 +1712,15 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
}
} else if (!cinfo->saw_JFIF_marker && !IS_EXIF(cinfo)) {
/*
- * IJG assumes all unidentified 3-channels are YCbCr.
- * We assume that only if the second two channels are
- * subsampled (either horizontally or vertically). If not,
- * we assume RGB.
- *
- * 4776576: Some digital cameras output YCbCr JPEG images
- * that do not contain a JFIF APP0 marker but are only
- * vertically subsampled (no horizontal subsampling).
- * We should only assume this is RGB data if the subsampling
- * factors for the second two channels are the same as the
- * first (check both horizontal and vertical factors).
+ * In the absence of certain markers, IJG has interpreted
+ * component id's of [1,2,3] as meaning YCbCr.We follow that
+ * interpretation, which is additionally described in the Image
+ * I/O JPEG metadata spec.If that condition is not met here the
+ * next step will be to examine the subsampling factors, if
+ * there is any difference in subsampling factors we also assume
+ * YCbCr, only if both horizontal and vertical subsampling
+ * is same we assume JPEG color space as RGB.
+ * This is also described in the Image I/O JPEG metadata spec.
*/
h_samp0 = cinfo->comp_info[0].h_samp_factor;
h_samp1 = cinfo->comp_info[1].h_samp_factor;
@@ -1731,8 +1730,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
v_samp1 = cinfo->comp_info[1].v_samp_factor;
v_samp2 = cinfo->comp_info[2].v_samp_factor;
- if ((h_samp1 == h_samp0) && (h_samp2 == h_samp0) &&
- (v_samp1 == v_samp0) && (v_samp2 == v_samp0))
+ cid0 = cinfo->comp_info[0].component_id;
+ cid1 = cinfo->comp_info[1].component_id;
+ cid2 = cinfo->comp_info[2].component_id;
+
+ if ((!(cid0 == 1 && cid1 == 2 && cid2 == 3)) &&
+ ((h_samp1 == h_samp0) && (h_samp2 == h_samp0) &&
+ (v_samp1 == v_samp0) && (v_samp2 == v_samp0)))
{
cinfo->jpeg_color_space = JCS_RGB;
/* output is already RGB, so it stays the same */
diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
index eba30a7e2af..20b7a9d7899 100644
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
@@ -413,6 +413,7 @@ public class XTrayIconPeer implements TrayIconPeer,
void addListeners() {
canvas.addMouseListener(eventProxy);
canvas.addMouseMotionListener(eventProxy);
+ eframe.addMouseListener(eventProxy);
}
long getWindow() {
diff --git a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
index 7782d543219..9587067a750 100644
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
@@ -926,7 +926,10 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
return copyflavors;
}
}
- return null;
+ DocFlavor[] flavor = new DocFlavor[2];
+ flavor[0] = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
+ flavor[1] = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
+ return flavor;
}
diff --git a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
index d9af8ddf6e1..e6597a4723c 100644
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
@@ -438,6 +438,15 @@ jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width
xsdo->drawable = drawable;
xsdo->isPixmap = JNI_FALSE;
} else {
+ /*
+ * width , height must be nonzero otherwise XCreatePixmap
+ * generates BadValue in error_handler
+ */
+ if (width <= 0 || height <= 0) {
+ JNU_ThrowOutOfMemoryError(env,
+ "Can't create offscreen surface");
+ return JNI_FALSE;
+ }
xsdo->isPixmap = JNI_TRUE;
/* REMIND: workaround for bug 4420220 on pgx32 boards:
don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java b/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
index ee50f24a293..815393eaa1c 100644
--- a/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
@@ -61,7 +61,7 @@ public final class Win32FontManager extends SunFontManager {
* enumerate (allow direct use) of EUDC fonts.
*/
eudcFont = new TrueTypeFont(eudcFile, null, 0,
- true);
+ true, false);
} catch (FontFormatException e) {
}
}
diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
index 7b0f8c29e06..257bbb72953 100644
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
@@ -48,8 +48,6 @@ import sun.awt.AWTPermissions;
@jdk.Exported
public class AWTEventMonitor {
- static private boolean runningOnJDK1_4 = false;
-
/**
* The current component with keyboard focus.
*
@@ -638,15 +636,9 @@ public class AWTEventMonitor {
* @see AWTEventMonitor
*/
public AWTEventsListener() {
- String version = System.getProperty("java.version");
- if (version != null) {
- runningOnJDK1_4 = (version.compareTo("1.4") >= 0);
- }
initializeIntrospection();
installListeners();
- if (runningOnJDK1_4) {
- MenuSelectionManager.defaultManager().addChangeListener(this);
- }
+ MenuSelectionManager.defaultManager().addChangeListener(this);
EventQueueMonitor.addTopLevelWindowListener(this);
}
@@ -848,15 +840,7 @@ public class AWTEventMonitor {
case EventID.FOCUS:
c.removeFocusListener(this);
c.addFocusListener(this);
-
- if (runningOnJDK1_4) {
- processFocusGained();
-
- } else { // not runningOnJDK1_4
- if ((c != componentWithFocus_private) && c.hasFocus()) {
- componentWithFocus_private = c;
- }
- }
+ processFocusGained();
break;
case EventID.ITEM:
diff --git a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
index ee1a63f5ec9..47832a4455b 100644
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
@@ -140,10 +140,6 @@ final public class AccessBridge {
// initialize AccessibleRole map
initAccessibleRoleMap();
- // determine which version of the JDK is running
- String version = getJavaVersionProperty();
- debugString("JDK version = "+version);
-
// initialize the methods that map HWNDs and Java top-level
// windows
initHWNDcalls();
@@ -215,9 +211,7 @@ final public class AccessBridge {
} catch (Exception e) {}
/*
- Build the extendedVirtualNameSearchRoles array list. I chose this method
- because some of the Accessible Roles that need to be added to it are not
- available in all versions of the J2SE that we want to support.
+ Build the extendedVirtualNameSearchRoles array list.
*/
extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX);
try {
@@ -5919,7 +5913,7 @@ final public class AccessBridge {
*/
AccessibleRole.UNKNOWN,
- // These roles are only available in JDK 1.4
+ // These roles are available since JDK 1.4
/**
* A STATUS_BAR is an simple component that can contain
diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java
new file mode 100644
index 00000000000..ec874229fdc
--- /dev/null
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java
@@ -0,0 +1,182 @@
+/*
+ * 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.nio.zipfs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+/**
+ * Adds aliasing to ZipFileSystem to support multi-release jar files. An alias map
+ * is created by {@link JarFileSystem#createVersionedLinks(int)}. The map is then
+ * consulted when an entry is looked up in {@link JarFileSystem#getEntry(byte[])}
+ * to determine if the entry has a corresponding versioned entry. If so, the
+ * versioned entry is returned.
+ *
+ * @author Steve Drach
+ */
+
+class JarFileSystem extends ZipFileSystem {
+ private Function lookup;
+
+ @Override
+ Entry getEntry(byte[] path) throws IOException {
+ // check for an alias to a versioned entry
+ byte[] versionedPath = lookup.apply(path);
+ return versionedPath == null ? super.getEntry(path) : super.getEntry(versionedPath);
+ }
+
+ JarFileSystem(ZipFileSystemProvider provider, Path zfpath, Map env)
+ throws IOException {
+ super(provider, zfpath, env);
+ lookup = path -> path; // lookup needs to be set before isMultiReleaseJar is called
+ // because it eventually calls getEntry
+ if (isMultiReleaseJar()) {
+ int version;
+ Object o = env.get("multi-release");
+ if (o instanceof String) {
+ String s = (String)o;
+ if (s.equals("runtime")) {
+ version = sun.misc.Version.jdkMajorVersion(); // fixme waiting for jdk.util.Version
+ } else {
+ version = Integer.parseInt(s);
+ }
+ } else if (o instanceof Integer) {
+ version = (Integer)o;
+ } else if (false /*o instanceof Version*/) { // fixme waiting for jdk.util.Version
+// version = ((Version)o).major();
+ } else {
+ throw new IllegalArgumentException("env parameter must be String, Integer, "
+ + "or Version");
+ }
+ lookup = createVersionedLinks(version < 0 ? 0 : version);
+ setReadOnly();
+ }
+ }
+
+ private boolean isMultiReleaseJar() {
+ try (InputStream is = newInputStream(getBytes("META-INF/MANIFEST.MF"))) {
+ return (new Manifest(is)).getMainAttributes()
+ .containsKey(new Attributes.Name("Multi-Release"));
+ // fixme change line above after JarFile integration to contain Attributes.Name.MULTI_RELEASE
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * create a map of aliases for versioned entries, for example:
+ * version/PackagePrivate.class -> META-INF/versions/9/version/PackagePrivate.class
+ * version/PackagePrivate.java -> META-INF/versions/9/version/PackagePrivate.java
+ * version/Version.class -> META-INF/versions/10/version/Version.class
+ * version/Version.java -> META-INF/versions/10/version/Version.java
+ *
+ * then wrap the map in a function that getEntry can use to override root
+ * entry lookup for entries that have corresponding versioned entries
+ */
+ private Function createVersionedLinks(int version) {
+ HashMap aliasMap = new HashMap<>();
+ getVersionMap(version, getInode(getBytes("META-INF/versions"))).values()
+ .forEach(versionNode -> { // for each META-INF/versions/{n} directory
+ // put all the leaf inodes, i.e. entries, into the alias map
+ // possibly shadowing lower versioned entries
+ walk(versionNode, entryNode -> {
+ byte[] rootName = getRootName(versionNode, entryNode);
+ if (rootName != null) {
+ IndexNode rootNode = getInode(rootName);
+ if (rootNode == null) { // no matching root node, make a virtual one
+ rootNode = IndexNode.keyOf(rootName);
+ }
+ aliasMap.put(rootNode, entryNode.name);
+ }
+ });
+ });
+ return path -> aliasMap.get(IndexNode.keyOf(path));
+ }
+
+ /**
+ * create a sorted version map of version -> inode, for inodes <= max version
+ * 9 -> META-INF/versions/9
+ * 10 -> META-INF/versions/10
+ */
+ private TreeMap getVersionMap(int version, IndexNode metaInfVersions) {
+ TreeMap map = new TreeMap<>();
+ IndexNode child = metaInfVersions.child;
+ while (child != null) {
+ Integer key = getVersion(child.name, metaInfVersions.name.length);
+ if (key != null && key <= version) {
+ map.put(key, child);
+ }
+ child = child.sibling;
+ }
+ return map;
+ }
+
+ /**
+ * extract the integer version number -- META-INF/versions/9 returns 9
+ */
+ private Integer getVersion(byte[] name, int offset) {
+ try {
+ return Integer.parseInt(getString(Arrays.copyOfRange(name, offset, name.length-1)));
+ } catch (NumberFormatException x) {
+ // ignore this even though it might indicate issues with the JAR structure
+ return null;
+ }
+ }
+
+ /**
+ * walk the IndexNode tree processing all leaf nodes
+ */
+ private void walk(IndexNode inode, Consumer process) {
+ if (inode == null) return;
+ if (inode.isDir()) {
+ walk(inode.child, process);
+ } else {
+ process.accept(inode);
+ walk(inode.sibling, process);
+ }
+ }
+
+ /**
+ * extract the root name from a versioned entry name
+ * given inode for META-INF/versions/9/foo/bar.class
+ * and prefix META-INF/versions/9/
+ * returns foo/bar.class
+ */
+ private byte[] getRootName(IndexNode prefix, IndexNode inode) {
+ int offset = prefix.name.length;
+ byte[] fullName = inode.name;
+ return Arrays.copyOfRange(fullName, offset, fullName.length);
+ }
+}
diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
index e269216c081..ae01cb38460 100644
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
@@ -155,6 +155,10 @@ class ZipFileSystem extends FileSystem {
throw new ReadOnlyFileSystemException();
}
+ void setReadOnly() {
+ this.readOnly = true;
+ }
+
@Override
public Iterable getRootDirectories() {
ArrayList pathArr = new ArrayList<>();
@@ -320,7 +324,7 @@ class ZipFileSystem extends FileSystem {
beginRead();
try {
ensureOpen();
- e = getEntry0(path);
+ e = getEntry(path);
if (e == null) {
IndexNode inode = getInode(path);
if (inode == null)
@@ -342,7 +346,7 @@ class ZipFileSystem extends FileSystem {
beginWrite();
try {
ensureOpen();
- Entry e = getEntry0(path); // ensureOpen checked
+ Entry e = getEntry(path); // ensureOpen checked
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.type == Entry.CEN)
@@ -445,7 +449,7 @@ class ZipFileSystem extends FileSystem {
beginWrite();
try {
ensureOpen();
- Entry eSrc = getEntry0(src); // ensureOpen checked
+ Entry eSrc = getEntry(src); // ensureOpen checked
if (eSrc == null)
throw new NoSuchFileException(getString(src));
if (eSrc.isDir()) { // spec says to create dst dir
@@ -460,7 +464,7 @@ class ZipFileSystem extends FileSystem {
else if (opt == COPY_ATTRIBUTES)
hasCopyAttrs = true;
}
- Entry eDst = getEntry0(dst);
+ Entry eDst = getEntry(dst);
if (eDst != null) {
if (!hasReplace)
throw new FileAlreadyExistsException(getString(dst));
@@ -521,7 +525,7 @@ class ZipFileSystem extends FileSystem {
beginRead(); // only need a readlock, the "update()" will
try { // try to obtain a writelock when the os is
ensureOpen(); // being closed.
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null) {
if (e.isDir() || hasCreateNew)
throw new FileAlreadyExistsException(getString(path));
@@ -550,7 +554,7 @@ class ZipFileSystem extends FileSystem {
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e == null)
throw new NoSuchFileException(getString(path));
if (e.isDir())
@@ -592,7 +596,7 @@ class ZipFileSystem extends FileSystem {
newOutputStream(path, options.toArray(new OpenOption[0])));
long leftover = 0;
if (options.contains(StandardOpenOption.APPEND)) {
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null && e.size >= 0)
leftover = e.size;
}
@@ -644,7 +648,7 @@ class ZipFileSystem extends FileSystem {
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e == null || e.isDir())
throw new NoSuchFileException(getString(path));
final ReadableByteChannel rbc =
@@ -714,7 +718,7 @@ class ZipFileSystem extends FileSystem {
beginRead();
try {
ensureOpen();
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (forWrite) {
checkWritable();
if (e == null) {
@@ -855,7 +859,7 @@ class ZipFileSystem extends FileSystem {
private Path getTempPathForEntry(byte[] path) throws IOException {
Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
if (path != null) {
- Entry e = getEntry0(path);
+ Entry e = getEntry(path);
if (e != null) {
try (InputStream is = newInputStream(path)) {
Files.copy(is, tmpPath, REPLACE_EXISTING);
@@ -939,7 +943,7 @@ class ZipFileSystem extends FileSystem {
private long getDataPos(Entry e) throws IOException {
if (e.locoff == -1) {
- Entry e2 = getEntry0(e.name);
+ Entry e2 = getEntry(e.name);
if (e2 == null)
throw new ZipException("invalid loc for entry <" + e.name + ">");
e.locoff = e2.locoff;
@@ -1325,7 +1329,7 @@ class ZipFileSystem extends FileSystem {
//System.out.printf("->sync(%s) done!%n", toString());
}
- private IndexNode getInode(byte[] path) {
+ IndexNode getInode(byte[] path) {
if (path == null)
throw new NullPointerException("path");
IndexNode key = IndexNode.keyOf(path);
@@ -1340,7 +1344,7 @@ class ZipFileSystem extends FileSystem {
return inode;
}
- private Entry getEntry0(byte[] path) throws IOException {
+ Entry getEntry(byte[] path) throws IOException {
IndexNode inode = getInode(path);
if (inode instanceof Entry)
return (Entry)inode;
@@ -2096,7 +2100,7 @@ class ZipFileSystem extends FileSystem {
pos += (LOCHDR + nlen + elen);
if ((flag & FLAG_DATADESCR) != 0) {
// Data Descriptor
- Entry e = zipfs.getEntry0(name); // get the size/csize from cen
+ Entry e = zipfs.getEntry(name); // get the size/csize from cen
if (e == null)
throw new ZipException("loc: name not found in cen");
size = e.size;
diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
index 3cb7ca49d39..c721c2fe175 100644
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java
@@ -100,7 +100,11 @@ public class ZipFileSystemProvider extends FileSystemProvider {
}
ZipFileSystem zipfs = null;
try {
- zipfs = new ZipFileSystem(this, path, env);
+ if (env.containsKey("multi-release")) {
+ zipfs = new JarFileSystem(this, path, env);
+ } else {
+ zipfs = new ZipFileSystem(this, path, env);
+ }
} catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
@@ -124,8 +128,14 @@ public class ZipFileSystemProvider extends FileSystemProvider {
throw new UnsupportedOperationException();
}
ensureFile(path);
- try {
- return new ZipFileSystem(this, path, env);
+ try {
+ ZipFileSystem zipfs;
+ if (env.containsKey("multi-release")) {
+ zipfs = new JarFileSystem(this, path, env);
+ } else {
+ zipfs = new ZipFileSystem(this, path, env);
+ }
+ return zipfs;
} catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index 51abaacbf53..2a18c6adef2 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -310,8 +310,6 @@ javax/sound/midi/Gervill/SoftProvider/GetDevice.java generic-all
# jdk_imageio
-javax/imageio/plugins/shared/WriteAfterAbort.java generic-all
-
############################################################################
# jdk_swing
diff --git a/jdk/test/java/awt/List/SetFontTest/SetFontTest.html b/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
index db33b8c83a8..3ac0d99fc51 100644
--- a/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
+++ b/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
@@ -38,6 +38,6 @@
See the dialog box (usually in upper left corner) for instructions
-
+