SecurityException
if the operation is not
* permitted.
*
- * The current security manager is set by the
- * setSecurityManager
method in class
- * System
. The current security manager is obtained
- * by the getSecurityManager
method.
+ * Environments using a security manager will typically set the security
+ * manager at startup. In the JDK implementation, this is done by setting
+ * the system property {@code java.security.manager} on the command line to
+ * the class name of the security manager. It can also be set to the empty
+ * String ("") or the special token "{@code default}" to use the
+ * default {@code java.lang.SecurityManager}. If a class name is specified,
+ * it must be {@code java.lang.SecurityManager} or a public subclass and have
+ * a public no-arg constructor. The class is loaded by the
+ * {@linkplain ClassLoader#getSystemClassLoader() built-in system class loader}
+ * if it is not {@code java.lang.SecurityManager}. If the
+ * {@code java.security.manager} system property is not set, the default value
+ * is {@code null}, which means a security manager will not be set at startup.
+ *
+ * The Java run-time may also allow, but is not required to allow, the security + * manager to be set dynamically by invoking the + * {@link System#setSecurityManager(SecurityManager) setSecurityManager} method. + * In the JDK implementation, if the Java virtual machine is started with + * the {@code java.security.manager} system property set to the special token + * "{@code disallow}" then a security manager will not be set at startup and + * cannot be set dynamically (the + * {@link System#setSecurityManager(SecurityManager) setSecurityManager} + * method will throw an {@code UnsupportedOperationException}). If the + * {@code java.security.manager} system property is not set or is set to the + * special token "{@code allow}", then a security manager will not be set at + * startup but can be set dynamically. Finally, if the + * {@code java.security.manager} system property is set to the class name of + * the security manager, or to the empty String ("") or the special token + * "{@code default}", then a security manager is set at startup (as described + * previously) and can also be subsequently replaced (or disabled) dynamically + * (subject to the policy of the currently installed security manager). The + * following table illustrates the behavior of the JDK implementation for the + * different settings of the {@code java.security.manager} system property: + *
Property Value | + *The SecurityManager set at startup | + *System.setSecurityManager run-time behavior | + *
---|---|---|
null | + *None | + *Success or throws {@code SecurityException} if not permitted by + * the currently installed security manager | + *
empty String ("") | + *{@code java.lang.SecurityManager} | + *Success or throws {@code SecurityException} if not permitted by + * the currently installed security manager | + *
"default" | + *{@code java.lang.SecurityManager} | + *Success or throws {@code SecurityException} if not permitted by + * the currently installed security manager | + *
"disallow" | + *None | + *Always throws {@code UnsupportedOperationException} | + *
"allow" | + *None | + *Success or throws {@code SecurityException} if not permitted by + * the currently installed security manager | + *
a class name | + *the named class | + *Success or throws {@code SecurityException} if not permitted by + * the currently installed security manager | + *
A future release of the JDK may change the default value of the + * {@code java.security.manager} system property to "{@code disallow}". + *
+ * The current security manager is returned by the + * {@link System#getSecurityManager() getSecurityManager} method. *
* The special method * {@link SecurityManager#checkPermission(java.security.Permission)} @@ -221,7 +308,6 @@ import sun.security.util.SecurityConstants; * @see java.net.SocketPermission * @see java.util.PropertyPermission * @see java.lang.RuntimePermission - * @see java.awt.AWTPermission * @see java.security.Policy Policy * @see java.security.SecurityPermission SecurityPermission * @see java.security.ProtectionDomain diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 88cd2977a55..8021951c84e 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -72,6 +72,7 @@ import jdk.internal.misc.VM; import jdk.internal.logger.LoggerFinderLoader; import jdk.internal.logger.LazyLoggers; import jdk.internal.logger.LocalizedLoggerWrapper; +import jdk.internal.vm.annotation.Stable; import sun.reflect.annotation.AnnotationType; import sun.nio.ch.Interruptible; import sun.security.util.SecurityConstants; @@ -154,9 +155,18 @@ public final class System { */ public static final PrintStream err = null; - /* The security manager for the system. - */ - private static volatile SecurityManager security; + // indicates if a security manager is possible + private static final int NEVER = 1; + private static final int MAYBE = 2; + private static @Stable int allowSecurityManager; + + // current security manager + private static volatile SecurityManager security; // read by VM + + // return true if a security manager is allowed + private static boolean allowSecurityManager() { + return (allowSecurityManager != NEVER); + } /** * Reassigns the "standard" input stream. @@ -231,6 +241,7 @@ public final class System { } private static volatile Console cons; + /** * Returns the unique {@link java.io.Console Console} object associated * with the current Java virtual machine, if any. @@ -292,7 +303,7 @@ public final class System { private static native void setErr0(PrintStream err); /** - * Sets the System security. + * Sets the system-wide security manager. * * If there is a security manager already installed, this method first * calls the security manager's {@code checkPermission} method @@ -306,27 +317,46 @@ public final class System { * security manager has been established, then no action is taken and * the method simply returns. * - * @param s the security manager. - * @throws SecurityException if the security manager has already - * been set and its {@code checkPermission} method - * doesn't allow it to be replaced. + * @implNote In the JDK implementation, if the Java virtual machine is + * started with the system property {@code java.security.manager} set to + * the special token "{@code disallow}" then the {@code setSecurityManager} + * method cannot be used to set a security manager. + * + * @param sm the security manager or {@code null} + * @throws SecurityException + * if the security manager has already been set and its {@code + * checkPermission} method doesn't allow it to be replaced + * @throws UnsupportedOperationException + * if {@code sm} is non-null and a security manager is not allowed + * to be set dynamically * @see #getSecurityManager * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission */ - public static void setSecurityManager(final SecurityManager s) { - if (security == null) { - // ensure image reader is initialized - Object.class.getResource("java/lang/ANY"); - } - if (s != null) { - try { - s.checkPackageAccess("java.lang"); - } catch (Exception e) { - // no-op + public static void setSecurityManager(SecurityManager sm) { + if (allowSecurityManager()) { + if (security == null) { + // ensure image reader is initialized + Object.class.getResource("java/lang/ANY"); + } + if (sm != null) { + try { + // pre-populates the SecurityManager.packageAccess cache + // to avoid recursive permission checking issues with custom + // SecurityManager implementations + sm.checkPackageAccess("java.lang"); + } catch (Exception e) { + // no-op + } + } + setSecurityManager0(sm); + } else { + // security manager not allowed + if (sm != null) { + throw new UnsupportedOperationException( + "Runtime configured to disallow security manager"); } } - setSecurityManager0(s); } private static synchronized @@ -335,13 +365,12 @@ public final class System { if (sm != null) { // ask the currently installed security manager if we // can replace it. - sm.checkPermission(new RuntimePermission - ("setSecurityManager")); + sm.checkPermission(new RuntimePermission("setSecurityManager")); } if ((s != null) && (s.getClass().getClassLoader() != null)) { // New security manager class is not on bootstrap classpath. - // Cause policy to get initialized before we install the new + // Force policy to get initialized before we install the new // security manager, in order to prevent infinite loops when // trying to initialize the policy (which usually involves // accessing some security and/or system properties, which in turn @@ -361,7 +390,7 @@ public final class System { } /** - * Gets the system security interface. + * Gets the system-wide security manager. * * @return if a security manager has already been established for the * current application, then that security manager is returned; @@ -369,7 +398,11 @@ public final class System { * @see #setSecurityManager */ public static SecurityManager getSecurityManager() { - return security; + if (allowSecurityManager()) { + return security; + } else { + return null; + } } /** @@ -2028,35 +2061,48 @@ public final class System { * 3. set TCCL * * This method must be called after the module system initialization. - * The security manager and system class loader may be custom class from + * The security manager and system class loader may be a custom class from * the application classpath or modulepath. */ private static void initPhase3() { - // set security manager - String cn = System.getProperty("java.security.manager"); - if (cn != null) { - if (cn.isEmpty() || "default".equals(cn)) { - System.setSecurityManager(new SecurityManager()); - } else { - try { - Class> c = Class.forName(cn, false, ClassLoader.getBuiltinAppClassLoader()); - Constructor> ctor = c.getConstructor(); - // Must be a public subclass of SecurityManager with - // a public no-arg constructor - if (!SecurityManager.class.isAssignableFrom(c) || + String smProp = System.getProperty("java.security.manager"); + if (smProp != null) { + switch (smProp) { + case "disallow": + allowSecurityManager = NEVER; + break; + case "allow": + allowSecurityManager = MAYBE; + break; + case "": + case "default": + setSecurityManager(new SecurityManager()); + allowSecurityManager = MAYBE; + break; + default: + try { + ClassLoader cl = ClassLoader.getBuiltinAppClassLoader(); + Class> c = Class.forName(smProp, false, cl); + Constructor> ctor = c.getConstructor(); + // Must be a public subclass of SecurityManager with + // a public no-arg constructor + if (!SecurityManager.class.isAssignableFrom(c) || !Modifier.isPublic(c.getModifiers()) || !Modifier.isPublic(ctor.getModifiers())) { - throw new Error("Could not create SecurityManager: " + ctor.toString()); + throw new Error("Could not create SecurityManager: " + + ctor.toString()); + } + // custom security manager may be in non-exported package + ctor.setAccessible(true); + SecurityManager sm = (SecurityManager) ctor.newInstance(); + setSecurityManager(sm); + } catch (Exception e) { + throw new InternalError("Could not create SecurityManager", e); } - // custom security manager implementation may be in unnamed module - // or a named module but non-exported package - ctor.setAccessible(true); - SecurityManager sm = (SecurityManager) ctor.newInstance(); - System.setSecurityManager(sm); - } catch (Exception e) { - throw new Error("Could not create SecurityManager", e); - } + allowSecurityManager = MAYBE; } + } else { + allowSecurityManager = MAYBE; } // initializing the system class loader diff --git a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html index 4c2c8158708..d5f31be7098 100644 --- a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html +++ b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html @@ -2,7 +2,7 @@
* out.writeByte(1); // identifies a Duration diff --git a/src/java.base/share/classes/java/time/Instant.java b/src/java.base/share/classes/java/time/Instant.java index 0aafa49fd40..8f38c76c20f 100644 --- a/src/java.base/share/classes/java/time/Instant.java +++ b/src/java.base/share/classes/java/time/Instant.java @@ -1332,7 +1332,7 @@ public final class Instant // ----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(2); // identifies an Instant diff --git a/src/java.base/share/classes/java/time/LocalDate.java b/src/java.base/share/classes/java/time/LocalDate.java index 0a89ec070c4..834a9e3e7df 100644 --- a/src/java.base/share/classes/java/time/LocalDate.java +++ b/src/java.base/share/classes/java/time/LocalDate.java @@ -2189,7 +2189,7 @@ public final class LocalDate //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(3); // identifies a LocalDate diff --git a/src/java.base/share/classes/java/time/LocalDateTime.java b/src/java.base/share/classes/java/time/LocalDateTime.java index 9a9ca87ddc3..8d3773a36eb 100644 --- a/src/java.base/share/classes/java/time/LocalDateTime.java +++ b/src/java.base/share/classes/java/time/LocalDateTime.java @@ -1975,12 +1975,12 @@ public final class LocalDateTime //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(5); // identifies a LocalDateTime - * // the date excluding the one byte header - * // the time excluding the one byte header + * // the date excluding the one byte header + * // the time excluding the one byte header ** * @return the instance of {@code Ser}, not null diff --git a/src/java.base/share/classes/java/time/LocalTime.java b/src/java.base/share/classes/java/time/LocalTime.java index 80241339c35..6f427f04d54 100644 --- a/src/java.base/share/classes/java/time/LocalTime.java +++ b/src/java.base/share/classes/java/time/LocalTime.java @@ -1645,7 +1645,7 @@ public final class LocalTime //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData * A twos-complement value indicates the remaining values are not in the stream * and should be set to zero. diff --git a/src/java.base/share/classes/java/time/MonthDay.java b/src/java.base/share/classes/java/time/MonthDay.java index c34a4f9c978..c8b5ca86921 100644 --- a/src/java.base/share/classes/java/time/MonthDay.java +++ b/src/java.base/share/classes/java/time/MonthDay.java @@ -754,7 +754,7 @@ public final class MonthDay //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(13); // identifies a MonthDay diff --git a/src/java.base/share/classes/java/time/OffsetDateTime.java b/src/java.base/share/classes/java/time/OffsetDateTime.java index 39b80bc1fc6..19ae55285f0 100644 --- a/src/java.base/share/classes/java/time/OffsetDateTime.java +++ b/src/java.base/share/classes/java/time/OffsetDateTime.java @@ -1915,12 +1915,12 @@ public final class OffsetDateTime //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(10); // identifies an OffsetDateTime - * // the datetime excluding the one byte header - * // the offset excluding the one byte header + * // the datetime excluding the one byte header + * // the offset excluding the one byte header ** * @return the instance of {@code Ser}, not null diff --git a/src/java.base/share/classes/java/time/OffsetTime.java b/src/java.base/share/classes/java/time/OffsetTime.java index b4e52743ba5..6301da8946a 100644 --- a/src/java.base/share/classes/java/time/OffsetTime.java +++ b/src/java.base/share/classes/java/time/OffsetTime.java @@ -1400,12 +1400,12 @@ public final class OffsetTime //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(9); // identifies an OffsetTime - * // the time excluding the one byte header - * // the offset excluding the one byte header + * // the time excluding the one byte header + * // the offset excluding the one byte header ** * @return the instance of {@code Ser}, not null diff --git a/src/java.base/share/classes/java/time/Period.java b/src/java.base/share/classes/java/time/Period.java index 726c52b742b..c0eef02ca1c 100644 --- a/src/java.base/share/classes/java/time/Period.java +++ b/src/java.base/share/classes/java/time/Period.java @@ -1041,7 +1041,7 @@ public final class Period //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(14); // identifies a Period diff --git a/src/java.base/share/classes/java/time/Ser.java b/src/java.base/share/classes/java/time/Ser.java index 885b43abd83..26cfc0b8ffc 100644 --- a/src/java.base/share/classes/java/time/Ser.java +++ b/src/java.base/share/classes/java/time/Ser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,20 +139,20 @@ final class Ser implements Externalizable { * in the stream. Refer to each class {@code writeReplace} * serialized form for the value of the type and sequence of values for the type. *
* out.writeByte(11); // identifies a Year diff --git a/src/java.base/share/classes/java/time/YearMonth.java b/src/java.base/share/classes/java/time/YearMonth.java index d1fa05b6243..40c88e4f6c5 100644 --- a/src/java.base/share/classes/java/time/YearMonth.java +++ b/src/java.base/share/classes/java/time/YearMonth.java @@ -1212,7 +1212,7 @@ public final class YearMonth //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(12); // identifies a YearMonth diff --git a/src/java.base/share/classes/java/time/ZoneId.java b/src/java.base/share/classes/java/time/ZoneId.java index 8bd135ab611..7f4ddbd4c8b 100644 --- a/src/java.base/share/classes/java/time/ZoneId.java +++ b/src/java.base/share/classes/java/time/ZoneId.java @@ -641,7 +641,7 @@ public abstract class ZoneId implements Serializable { //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(7); // identifies a ZoneId (not ZoneOffset) diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 29b5909a57d..cc7186e8c0c 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -750,7 +750,7 @@ public final class ZoneOffset // ----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(8); // identifies a ZoneOffset diff --git a/src/java.base/share/classes/java/time/ZoneRegion.java b/src/java.base/share/classes/java/time/ZoneRegion.java index 83f0b43d775..cf92d7459b3 100644 --- a/src/java.base/share/classes/java/time/ZoneRegion.java +++ b/src/java.base/share/classes/java/time/ZoneRegion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -180,7 +180,7 @@ final class ZoneRegion extends ZoneId implements Serializable { //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(7); // identifies a ZoneId (not ZoneOffset) diff --git a/src/java.base/share/classes/java/time/ZonedDateTime.java b/src/java.base/share/classes/java/time/ZonedDateTime.java index 7d50644a3f7..7c89759ed18 100644 --- a/src/java.base/share/classes/java/time/ZonedDateTime.java +++ b/src/java.base/share/classes/java/time/ZonedDateTime.java @@ -2224,13 +2224,13 @@ public final class ZonedDateTime //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(6); // identifies a ZonedDateTime - * // the dateTime excluding the one byte header - * // the offset excluding the one byte header - * // the zone ID excluding the one byte header + * // the dateTime excluding the one byte header + * // the offset excluding the one byte header + * // the zone ID excluding the one byte header ** * @return the instance of {@code Ser}, not null diff --git a/src/java.base/share/classes/java/time/chrono/AbstractChronology.java b/src/java.base/share/classes/java/time/chrono/AbstractChronology.java index a32ecb78da1..e886975fb6d 100644 --- a/src/java.base/share/classes/java/time/chrono/AbstractChronology.java +++ b/src/java.base/share/classes/java/time/chrono/AbstractChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -721,7 +721,7 @@ public abstract class AbstractChronology implements Chronology { //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. ** out.writeByte(1); // identifies this as a Chronology * out.writeUTF(getId()); diff --git a/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index ac5f7b4bfe3..4460a7a8aa4 100644 --- a/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/src/java.base/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -399,7 +399,7 @@ final class ChronoLocalDateTimeImpl//----------------------------------------------------------------------- /** * Writes the ChronoLocalDateTime using a - * dedicated serialized form. + * dedicated serialized form. * @serialData * * out.writeByte(2); // identifies a ChronoLocalDateTime diff --git a/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java b/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java index 646af14d05a..b2b9ddb610f 100644 --- a/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java +++ b/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -355,7 +355,7 @@ final class ChronoPeriodImpl //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. ** out.writeByte(12); // identifies this as a ChronoPeriodImpl * out.writeUTF(getId()); // the chronology diff --git a/src/java.base/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/src/java.base/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index abd21eecaf0..aa5f0ab11ff 100644 --- a/src/java.base/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/src/java.base/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -322,7 +322,7 @@ final class ChronoZonedDateTimeImpl//----------------------------------------------------------------------- /** * Writes the ChronoZonedDateTime using a - * dedicated serialized form. + * dedicated serialized form. * @serialData * * out.writeByte(3); // identifies a ChronoZonedDateTime diff --git a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index bc702a44d07..864cfa941c7 100644 --- a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1011,7 +1011,7 @@ public final class HijrahChronology extends AbstractChronology implements Serial //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(1); // identifies a Chronology diff --git a/src/java.base/share/classes/java/time/chrono/HijrahDate.java b/src/java.base/share/classes/java/time/chrono/HijrahDate.java index 48b506044c0..632aca1d73f 100644 --- a/src/java.base/share/classes/java/time/chrono/HijrahDate.java +++ b/src/java.base/share/classes/java/time/chrono/HijrahDate.java @@ -663,7 +663,7 @@ public final class HijrahDate /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(6); // identifies a HijrahDate diff --git a/src/java.base/share/classes/java/time/chrono/IsoChronology.java b/src/java.base/share/classes/java/time/chrono/IsoChronology.java index 18d73689569..431aaca214c 100644 --- a/src/java.base/share/classes/java/time/chrono/IsoChronology.java +++ b/src/java.base/share/classes/java/time/chrono/IsoChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -680,7 +680,7 @@ public final class IsoChronology extends AbstractChronology implements Serializa //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(1); // identifies a Chronology diff --git a/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java b/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java index 8cd67a05908..ed2d9172a07 100644 --- a/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java +++ b/src/java.base/share/classes/java/time/chrono/JapaneseChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -507,7 +507,7 @@ public final class JapaneseChronology extends AbstractChronology implements Seri //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(1); // identifies a Chronology diff --git a/src/java.base/share/classes/java/time/chrono/JapaneseDate.java b/src/java.base/share/classes/java/time/chrono/JapaneseDate.java index 92437c3d714..e6d72ded676 100644 --- a/src/java.base/share/classes/java/time/chrono/JapaneseDate.java +++ b/src/java.base/share/classes/java/time/chrono/JapaneseDate.java @@ -725,7 +725,7 @@ public final class JapaneseDate /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(4); // identifies a JapaneseDate diff --git a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java b/src/java.base/share/classes/java/time/chrono/JapaneseEra.java index 3d318ea36b0..a9bbc5e276e 100644 --- a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java +++ b/src/java.base/share/classes/java/time/chrono/JapaneseEra.java @@ -395,7 +395,7 @@ public final class JapaneseEra //----------------------------------------------------------------------- /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(5); // identifies a JapaneseEra diff --git a/src/java.base/share/classes/java/time/chrono/MinguoChronology.java b/src/java.base/share/classes/java/time/chrono/MinguoChronology.java index fd6fdc3e8cd..647292303e2 100644 --- a/src/java.base/share/classes/java/time/chrono/MinguoChronology.java +++ b/src/java.base/share/classes/java/time/chrono/MinguoChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -337,7 +337,7 @@ public final class MinguoChronology extends AbstractChronology implements Serial //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(1); // identifies a Chronology diff --git a/src/java.base/share/classes/java/time/chrono/MinguoDate.java b/src/java.base/share/classes/java/time/chrono/MinguoDate.java index c827b662871..b7caf9c6410 100644 --- a/src/java.base/share/classes/java/time/chrono/MinguoDate.java +++ b/src/java.base/share/classes/java/time/chrono/MinguoDate.java @@ -487,7 +487,7 @@ public final class MinguoDate /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(8); // identifies a MinguoDate diff --git a/src/java.base/share/classes/java/time/chrono/Ser.java b/src/java.base/share/classes/java/time/chrono/Ser.java index 317a7696497..6ecef928d79 100644 --- a/src/java.base/share/classes/java/time/chrono/Ser.java +++ b/src/java.base/share/classes/java/time/chrono/Ser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,18 +136,18 @@ final class Ser implements Externalizable { * in the stream. Refer to each class {@code writeReplace} * serialized form for the value of the type and sequence of values for the type. *- *
* * @param out the data stream to write to, not null @@ -202,18 +202,18 @@ final class Ser implements Externalizable { * {@code Ser} object. * *- HijrahChronology.writeReplace - *
- IsoChronology.writeReplace - *
- JapaneseChronology.writeReplace - *
- MinguoChronology.writeReplace - *
- ThaiBuddhistChronology.writeReplace - *
- ChronoLocalDateTime.writeReplace - *
- ChronoZonedDateTime.writeReplace - *
- JapaneseDate.writeReplace - *
- JapaneseEra.writeReplace - *
- HijrahDate.writeReplace - *
- MinguoDate.writeReplace - *
- ThaiBuddhistDate.writeReplace + *
- HijrahChronology.writeReplace + *
- IsoChronology.writeReplace + *
- JapaneseChronology.writeReplace + *
- MinguoChronology.writeReplace + *
- ThaiBuddhistChronology.writeReplace + *
- ChronoLocalDateTime.writeReplace + *
- ChronoZonedDateTime.writeReplace + *
- JapaneseDate.writeReplace + *
- JapaneseEra.writeReplace + *
- HijrahDate.writeReplace + *
- MinguoDate.writeReplace + *
- ThaiBuddhistDate.writeReplace *
- *
* * @param in the data stream to read from, not null diff --git a/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java b/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java index c6938b2c530..982aa57017e 100644 --- a/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java +++ b/src/java.base/share/classes/java/time/chrono/ThaiBuddhistChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -374,7 +374,7 @@ public final class ThaiBuddhistChronology extends AbstractChronology implements //----------------------------------------------------------------------- /** * Writes the Chronology using a - * dedicated serialized form. + * dedicated serialized form. * @serialData *- HijrahChronology - Chronology.of(id) - *
- IsoChronology - Chronology.of(id) - *
- JapaneseChronology - Chronology.of(id) - *
- MinguoChronology - Chronology.of(id) - *
- ThaiBuddhistChronology - Chronology.of(id) - *
- ChronoLocalDateTime - date.atTime(time) - *
- ChronoZonedDateTime - dateTime.atZone(offset).withZoneSameLocal(zone) - *
- JapaneseDate - JapaneseChronology.INSTANCE.date(year, month, dayOfMonth) - *
- JapaneseEra - JapaneseEra.of(eraValue) - *
- HijrahDate - HijrahChronology chrono.date(year, month, dayOfMonth) - *
- MinguoDate - MinguoChronology.INSTANCE.date(year, month, dayOfMonth) - *
- ThaiBuddhistDate - ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth) + *
- HijrahChronology - Chronology.of(id) + *
- IsoChronology - Chronology.of(id) + *
- JapaneseChronology - Chronology.of(id) + *
- MinguoChronology - Chronology.of(id) + *
- ThaiBuddhistChronology - Chronology.of(id) + *
- ChronoLocalDateTime - date.atTime(time) + *
- ChronoZonedDateTime - dateTime.atZone(offset).withZoneSameLocal(zone) + *
- JapaneseDate - JapaneseChronology.INSTANCE.date(year, month, dayOfMonth) + *
- JapaneseEra - JapaneseEra.of(eraValue) + *
- HijrahDate - HijrahChronology chrono.date(year, month, dayOfMonth) + *
- MinguoDate - MinguoChronology.INSTANCE.date(year, month, dayOfMonth) + *
- ThaiBuddhistDate - ThaiBuddhistChronology.INSTANCE.date(year, month, dayOfMonth) *
* out.writeByte(1); // identifies a Chronology diff --git a/src/java.base/share/classes/java/time/chrono/ThaiBuddhistDate.java b/src/java.base/share/classes/java/time/chrono/ThaiBuddhistDate.java index 276905c0f37..6db40aa571d 100644 --- a/src/java.base/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/src/java.base/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -487,7 +487,7 @@ public final class ThaiBuddhistDate /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData ** out.writeByte(10); // identifies a ThaiBuddhistDate diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 199313df7e1..3d3cd956c49 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -1138,9 +1138,12 @@ public final class DateTimeFormatter { ** This returns an immutable formatter capable of formatting and parsing * the ISO-8601 instant format. - * When formatting, the second-of-minute is always output. + * When formatting, the instant will always be suffixed by 'Z' to indicate UTC. + * The second-of-minute is always output. * The nano-of-second outputs zero, three, six or nine digits as necessary. - * When parsing, time to at least the seconds field is required. + * When parsing, the behaviour of {@link DateTimeFormatterBuilder#appendOffsetId()} + * will be used to parse the offset, converting the instant to UTC as necessary. + * The time to at least the seconds field is required. * Fractional seconds from zero to nine are parsed. * The localized decimal style is not used. *
diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index 28e58797b47..ca37005fe8a 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -837,6 +837,10 @@ public final class DateTimeFormatterBuilder { * The leap-second time of '23:59:59' is handled to some degree, see * {@link DateTimeFormatter#parsedLeapSecond()} for full details. *
+ * When formatting, the instant will always be suffixed by 'Z' to indicate UTC. + * When parsing, the behaviour of {@link DateTimeFormatterBuilder#appendOffsetId()} + * will be used to parse the offset, converting the instant to UTC as necessary. + *
* An alternative to this method is to format/parse the instant as a single * epoch-seconds value. That is achieved using {@code appendValue(INSTANT_SECONDS)}. * @@ -3468,7 +3472,7 @@ public final class DateTimeFormatterBuilder { .appendValue(MINUTE_OF_HOUR, 2).appendLiteral(':') .appendValue(SECOND_OF_MINUTE, 2) .appendFraction(NANO_OF_SECOND, minDigits, maxDigits, true) - .appendLiteral('Z') + .appendOffsetId() .toFormatter().toPrinterParser(false); DateTimeParseContext newContext = context.copy(); int pos = parser.parse(newContext, text, position); @@ -3486,6 +3490,7 @@ public final class DateTimeFormatterBuilder { Long nanoVal = newContext.getParsed(NANO_OF_SECOND); int sec = (secVal != null ? secVal.intValue() : 0); int nano = (nanoVal != null ? nanoVal.intValue() : 0); + int offset = newContext.getParsed(OFFSET_SECONDS).intValue(); int days = 0; if (hour == 24 && min == 0 && sec == 0 && nano == 0) { hour = 0; @@ -3498,7 +3503,7 @@ public final class DateTimeFormatterBuilder { long instantSecs; try { LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, min, sec, 0).plusDays(days); - instantSecs = ldt.toEpochSecond(ZoneOffset.UTC); + instantSecs = ldt.toEpochSecond(ZoneOffset.ofTotalSeconds(offset)); instantSecs += Math.multiplyExact(yearParsed / 10_000L, SECONDS_PER_10000_YEARS); } catch (RuntimeException ex) { return ~position; diff --git a/src/java.base/share/classes/java/time/zone/Ser.java b/src/java.base/share/classes/java/time/zone/Ser.java index 31c2f2d2bc1..59196465a88 100644 --- a/src/java.base/share/classes/java/time/zone/Ser.java +++ b/src/java.base/share/classes/java/time/zone/Ser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,9 +125,9 @@ final class Ser implements Externalizable { * serialized form for the value of the type and sequence of values for the type. * *
- *
* * @param out the data stream to write to, not null @@ -168,11 +168,11 @@ final class Ser implements Externalizable { * {@code Ser} object. * *- ZoneRules.writeReplace - *
- ZoneOffsetTransition.writeReplace - *
- ZoneOffsetTransitionRule.writeReplace + *
- ZoneRules.writeReplace + *
- ZoneOffsetTransition.writeReplace + *
- ZoneOffsetTransitionRule.writeReplace *
- *
* @param in the data to read, not null diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java index 94264f32cce..6d108e277a0 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -190,10 +190,10 @@ public final class ZoneOffsetTransition /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData * Refer to the serialized form of - * ZoneRules.writeReplace + * ZoneRules.writeReplace * for the encoding of epoch seconds and offsets. *- ZoneRules + *
- ZoneRules * - {@code ZoneRules.of(standardTransitions, standardOffsets, savingsInstantTransitions, wallOffsets, lastRules);} - *
- ZoneOffsetTransition + *
- ZoneOffsetTransition * - {@code ZoneOffsetTransition of(LocalDateTime.ofEpochSecond(epochSecond), offsetBefore, offsetAfter);} - *
- ZoneOffsetTransitionRule + *
- ZoneOffsetTransitionRule * - {@code ZoneOffsetTransitionRule.of(month, dom, dow, time, timeEndOfDay, timeDefinition, standardOffset, offsetBefore, offsetAfter);} *
{@code * diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java index 9c700d5ec70..dc95f3ecde4 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -249,10 +249,10 @@ public final class ZoneOffsetTransitionRule implements Serializable { /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData * Refer to the serialized form of - * ZoneRules.writeReplace + * ZoneRules.writeReplace * for the encoding of epoch seconds and offsets. *{@code * diff --git a/src/java.base/share/classes/java/time/zone/ZoneRules.java b/src/java.base/share/classes/java/time/zone/ZoneRules.java index f2dee70fee6..0cb381da05e 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneRules.java +++ b/src/java.base/share/classes/java/time/zone/ZoneRules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -327,7 +327,7 @@ public final class ZoneRules implements Serializable { /** * Writes the object using a - * dedicated serialized form. + * dedicated serialized form. * @serialData *{@code * diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index f58b67b8ef8..50f92e2ec14 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -2246,22 +2246,26 @@ public final class Locale implements Cloneable, Serializable { /** * @serialField language String - * language subtag in lower case. (See getLanguage()) + * language subtag in lower case. + * (See getLanguage()) * @serialField country String - * country subtag in upper case. (See getCountry()) + * country subtag in upper case. + * (See getCountry()) * @serialField variant String - * variant subtags separated by LOWLINE characters. (See getVariant()) + * variant subtags separated by LOWLINE characters. + * (See getVariant()) * @serialField hashcode int * deprecated, for forward compatibility only * @serialField script String - * script subtag in title case (See getScript()) + * script subtag in title case + * (See getScript()) * @serialField extensions String * canonical representation of extensions, that is, * BCP47 extensions in alphabetical order followed by * BCP47 private use subtags, all in lower case letters * separated by HYPHEN-MINUS characters. - * (See getExtensionKeys(), - * getExtension(char)) + * (See getExtensionKeys(), + * getExtension(char)) */ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("language", String.class), diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index 5d4b7e0db8b..61b7c1613e9 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java @@ -550,7 +550,7 @@ public class Attributes implements Map