From a7739ef564e5f52403700eac9ec6183a14c46394 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Mon, 28 Mar 2016 17:12:48 +0300 Subject: [PATCH 01/54] 8073872: Schemagen fails with StackOverflowError if element references containing class Reviewed-by: lancea --- jdk/test/javax/xml/bind/jxc/8073872/Foo.java | 45 +++++++++++ .../jxc/8073872/SchemagenStackOverflow.java | 78 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 jdk/test/javax/xml/bind/jxc/8073872/Foo.java create mode 100644 jdk/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java diff --git a/jdk/test/javax/xml/bind/jxc/8073872/Foo.java b/jdk/test/javax/xml/bind/jxc/8073872/Foo.java new file mode 100644 index 00000000000..9a2e3d60b53 --- /dev/null +++ b/jdk/test/javax/xml/bind/jxc/8073872/Foo.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = {"fooObject"}) +@XmlRootElement(name = "Foo") + +public class Foo { + + protected List fooObject; + + public List getFooObject() { + if (fooObject == null) { + fooObject = new ArrayList(); + } + return this.fooObject; + } +} diff --git a/jdk/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java b/jdk/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java new file mode 100644 index 00000000000..f1f143de529 --- /dev/null +++ b/jdk/test/javax/xml/bind/jxc/8073872/SchemagenStackOverflow.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8073872 + * @summary test that stackoverflow is not observable when element + * references containing class + * @modules java.xml + * @modules java.xml.bind + * @compile Foo.java + * @run testng/othervm SchemagenStackOverflow + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.SchemaOutputResolver; +import javax.xml.transform.Result; +import javax.xml.transform.stream.StreamResult; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class SchemagenStackOverflow { + + @Test + public void schemagenStackOverflowTest() throws Exception { + // Create new instance of JAXB context + JAXBContext context = JAXBContext.newInstance(Foo.class); + context.generateSchema(new TestOutputResolver()); + + // Read schema content from file + String content = Files.lines(resultSchemaFile).collect(Collectors.joining("")); + System.out.println("Generated schema content:" + content); + + // Check if schema was generated: check class and list object names + Assert.assertTrue(content.contains("name=\"Foo\"")); + Assert.assertTrue(content.contains("name=\"fooObject\"")); + } + + // Schemagen output resolver + class TestOutputResolver extends SchemaOutputResolver { + @Override + public Result createOutput(String namespaceUri, String fileName) + throws IOException { + return new StreamResult(resultSchemaFile.toFile()); + } + } + + // Schemagen output file name and path + static final String SCHEMA_FILENAME = "generatedSchema.xsd"; + Path resultSchemaFile = Paths.get(System.getProperty("user.dir", ".")) + .resolve(SCHEMA_FILENAME); + +} From 837a779be871efedf93b6b9158112a2607214659 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 28 Mar 2016 08:53:39 -0700 Subject: [PATCH 02/54] 8152083: Optimize TimeUnit conversions Reviewed-by: martin, shade, forax --- .../java/util/concurrent/TimeUnit.java | 263 +++++++++--------- .../util/concurrent/tck/TimeUnit8Test.java | 103 +++++++ .../util/concurrent/tck/TimeUnitTest.java | 216 +++++++++++--- 3 files changed, 409 insertions(+), 173 deletions(-) create mode 100644 jdk/test/java/util/concurrent/tck/TimeUnit8Test.java diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java b/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java index 1395886faa5..2f481b04236 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/TimeUnit.java @@ -75,136 +75,93 @@ public enum TimeUnit { /** * Time unit representing one thousandth of a microsecond. */ - NANOSECONDS { - public long toNanos(long d) { return d; } - public long toMicros(long d) { return d/(C1/C0); } - public long toMillis(long d) { return d/(C2/C0); } - public long toSeconds(long d) { return d/(C3/C0); } - public long toMinutes(long d) { return d/(C4/C0); } - public long toHours(long d) { return d/(C5/C0); } - public long toDays(long d) { return d/(C6/C0); } - public long convert(long d, TimeUnit u) { return u.toNanos(d); } - int excessNanos(long d, long m) { return (int)(d - (m*C2)); } - }, - + NANOSECONDS(TimeUnit.NANO_SCALE), /** * Time unit representing one thousandth of a millisecond. */ - MICROSECONDS { - public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); } - public long toMicros(long d) { return d; } - public long toMillis(long d) { return d/(C2/C1); } - public long toSeconds(long d) { return d/(C3/C1); } - public long toMinutes(long d) { return d/(C4/C1); } - public long toHours(long d) { return d/(C5/C1); } - public long toDays(long d) { return d/(C6/C1); } - public long convert(long d, TimeUnit u) { return u.toMicros(d); } - int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); } - }, - + MICROSECONDS(TimeUnit.MICRO_SCALE), /** * Time unit representing one thousandth of a second. */ - MILLISECONDS { - public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); } - public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); } - public long toMillis(long d) { return d; } - public long toSeconds(long d) { return d/(C3/C2); } - public long toMinutes(long d) { return d/(C4/C2); } - public long toHours(long d) { return d/(C5/C2); } - public long toDays(long d) { return d/(C6/C2); } - public long convert(long d, TimeUnit u) { return u.toMillis(d); } - int excessNanos(long d, long m) { return 0; } - }, - + MILLISECONDS(TimeUnit.MILLI_SCALE), /** * Time unit representing one second. */ - SECONDS { - public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); } - public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); } - public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); } - public long toSeconds(long d) { return d; } - public long toMinutes(long d) { return d/(C4/C3); } - public long toHours(long d) { return d/(C5/C3); } - public long toDays(long d) { return d/(C6/C3); } - public long convert(long d, TimeUnit u) { return u.toSeconds(d); } - int excessNanos(long d, long m) { return 0; } - }, - + SECONDS(TimeUnit.SECOND_SCALE), /** * Time unit representing sixty seconds. * @since 1.6 */ - MINUTES { - public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); } - public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); } - public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); } - public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); } - public long toMinutes(long d) { return d; } - public long toHours(long d) { return d/(C5/C4); } - public long toDays(long d) { return d/(C6/C4); } - public long convert(long d, TimeUnit u) { return u.toMinutes(d); } - int excessNanos(long d, long m) { return 0; } - }, - + MINUTES(TimeUnit.MINUTE_SCALE), /** * Time unit representing sixty minutes. * @since 1.6 */ - HOURS { - public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); } - public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); } - public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); } - public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); } - public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); } - public long toHours(long d) { return d; } - public long toDays(long d) { return d/(C6/C5); } - public long convert(long d, TimeUnit u) { return u.toHours(d); } - int excessNanos(long d, long m) { return 0; } - }, - + HOURS(TimeUnit.HOUR_SCALE), /** * Time unit representing twenty four hours. * @since 1.6 */ - DAYS { - public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); } - public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); } - public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); } - public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); } - public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); } - public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); } - public long toDays(long d) { return d; } - public long convert(long d, TimeUnit u) { return u.toDays(d); } - int excessNanos(long d, long m) { return 0; } - }; + DAYS(TimeUnit.DAY_SCALE); - // Handy constants for conversion methods - static final long C0 = 1L; - static final long C1 = C0 * 1000L; - static final long C2 = C1 * 1000L; - static final long C3 = C2 * 1000L; - static final long C4 = C3 * 60L; - static final long C5 = C4 * 60L; - static final long C6 = C5 * 24L; + // Scales as constants + private static final long NANO_SCALE = 1L; + private static final long MICRO_SCALE = 1000L * NANO_SCALE; + private static final long MILLI_SCALE = 1000L * MICRO_SCALE; + private static final long SECOND_SCALE = 1000L * MILLI_SCALE; + private static final long MINUTE_SCALE = 60L * SECOND_SCALE; + private static final long HOUR_SCALE = 60L * MINUTE_SCALE; + private static final long DAY_SCALE = 24L * HOUR_SCALE; - static final long MAX = Long.MAX_VALUE; - - /** - * Scale d by m, checking for overflow. - * This has a short name to make above code more readable. + /* + * Instances cache conversion ratios and saturation cutoffs for + * the units up through SECONDS. Other cases compute them, in + * method cvt. */ - static long x(long d, long m, long over) { - if (d > +over) return Long.MAX_VALUE; - if (d < -over) return Long.MIN_VALUE; - return d * m; + + private final long scale; + private final long maxNanos; + private final long maxMicros; + private final long maxMillis; + private final long maxSecs; + private final long microRatio; + private final int milliRatio; // fits in 32 bits + private final int secRatio; // fits in 32 bits + + private TimeUnit(long s) { + this.scale = s; + this.maxNanos = Long.MAX_VALUE / s; + long ur = (s >= MICRO_SCALE) ? (s / MICRO_SCALE) : (MICRO_SCALE / s); + this.microRatio = ur; + this.maxMicros = Long.MAX_VALUE / ur; + long mr = (s >= MILLI_SCALE) ? (s / MILLI_SCALE) : (MILLI_SCALE / s); + this.milliRatio = (int)mr; + this.maxMillis = Long.MAX_VALUE / mr; + long sr = (s >= SECOND_SCALE) ? (s / SECOND_SCALE) : (SECOND_SCALE / s); + this.secRatio = (int)sr; + this.maxSecs = Long.MAX_VALUE / sr; } - // To maintain full signature compatibility with 1.5, and to improve the - // clarity of the generated javadoc (see 6287639: Abstract methods in - // enum classes should not be listed as abstract), method convert - // etc. are not declared abstract but otherwise act as abstract methods. + /** + * General conversion utility. + * + * @param d duration + * @param dst result unit scale + * @param src source unit scale + */ + private static long cvt(long d, long dst, long src) { + long r, m; + if (src == dst) + return d; + else if (src < dst) + return d / (dst / src); + else if (d > (m = Long.MAX_VALUE / (r = src / dst))) + return Long.MAX_VALUE; + else if (d < -m) + return Long.MIN_VALUE; + else + return d * r; + } /** * Converts the given time duration in the given unit to this unit. @@ -221,11 +178,17 @@ public enum TimeUnit { * @param sourceDuration the time duration in the given {@code sourceUnit} * @param sourceUnit the unit of the {@code sourceDuration} argument * @return the converted duration in this unit, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. */ public long convert(long sourceDuration, TimeUnit sourceUnit) { - throw new AbstractMethodError(); + switch (this) { + case NANOSECONDS: return sourceUnit.toNanos(sourceDuration); + case MICROSECONDS: return sourceUnit.toMicros(sourceDuration); + case MILLISECONDS: return sourceUnit.toMillis(sourceDuration); + case SECONDS: return sourceUnit.toSeconds(sourceDuration); + default: return cvt(sourceDuration, scale, sourceUnit.scale); + } } /** @@ -233,11 +196,19 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toNanos(long duration) { - throw new AbstractMethodError(); + long s, m; + if ((s = scale) == NANO_SCALE) + return duration; + else if (duration > (m = maxNanos)) + return Long.MAX_VALUE; + else if (duration < -m) + return Long.MIN_VALUE; + else + return duration * s; } /** @@ -245,11 +216,21 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toMicros(long duration) { - throw new AbstractMethodError(); + long s, m; + if ((s = scale) == MICRO_SCALE) + return duration; + else if (s < MICRO_SCALE) + return duration / microRatio; + else if (duration > (m = maxMicros)) + return Long.MAX_VALUE; + else if (duration < -m) + return Long.MIN_VALUE; + else + return duration * microRatio; } /** @@ -257,11 +238,21 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toMillis(long duration) { - throw new AbstractMethodError(); + long s, m; + if ((s = scale) == MILLI_SCALE) + return duration; + else if (s < MILLI_SCALE) + return duration / milliRatio; + else if (duration > (m = maxMillis)) + return Long.MAX_VALUE; + else if (duration < -m) + return Long.MIN_VALUE; + else + return duration * milliRatio; } /** @@ -269,11 +260,21 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. */ public long toSeconds(long duration) { - throw new AbstractMethodError(); + long s, m; + if ((s = scale) == SECOND_SCALE) + return duration; + else if (s < SECOND_SCALE) + return duration / secRatio; + else if (duration > (m = maxSecs)) + return Long.MAX_VALUE; + else if (duration < -m) + return Long.MIN_VALUE; + else + return duration * secRatio; } /** @@ -281,12 +282,12 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. * @since 1.6 */ public long toMinutes(long duration) { - throw new AbstractMethodError(); + return cvt(duration, MINUTE_SCALE, scale); } /** @@ -294,12 +295,12 @@ public enum TimeUnit { * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}. * @param duration the duration * @return the converted duration, - * or {@code Long.MIN_VALUE} if conversion would negatively - * overflow, or {@code Long.MAX_VALUE} if it would positively overflow. + * or {@code Long.MIN_VALUE} if conversion would negatively overflow, + * or {@code Long.MAX_VALUE} if it would positively overflow. * @since 1.6 */ public long toHours(long duration) { - throw new AbstractMethodError(); + return cvt(duration, HOUR_SCALE, scale); } /** @@ -310,7 +311,7 @@ public enum TimeUnit { * @since 1.6 */ public long toDays(long duration) { - throw new AbstractMethodError(); + return cvt(duration, DAY_SCALE, scale); } /** @@ -320,7 +321,15 @@ public enum TimeUnit { * @param m the number of milliseconds * @return the number of nanoseconds */ - abstract int excessNanos(long d, long m); + private int excessNanos(long d, long m) { + long s; + if ((s = scale) == NANO_SCALE) + return (int)(d - (m * MILLI_SCALE)); + else if (s == MICRO_SCALE) + return (int)((d * 1000L) - (m * MILLI_SCALE)); + else + return 0; + } /** * Performs a timed {@link Object#wait(long, int) Object.wait} diff --git a/jdk/test/java/util/concurrent/tck/TimeUnit8Test.java b/jdk/test/java/util/concurrent/tck/TimeUnit8Test.java new file mode 100644 index 00000000000..b5fa1813cb2 --- /dev/null +++ b/jdk/test/java/util/concurrent/tck/TimeUnit8Test.java @@ -0,0 +1,103 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea and Martin Buchholz with assistance from + * members of JCP JSR-166 Expert Group and released to the public + * domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class TimeUnit8Test extends JSR166TestCase { + public static void main(String[] args) { + main(suite(), args); + } + + public static Test suite() { + return new TestSuite(TimeUnit8Test.class); + } + + /** + * tests for toChronoUnit. + */ + public void testToChronoUnit() throws Exception { + assertSame(ChronoUnit.NANOS, NANOSECONDS.toChronoUnit()); + assertSame(ChronoUnit.MICROS, MICROSECONDS.toChronoUnit()); + assertSame(ChronoUnit.MILLIS, MILLISECONDS.toChronoUnit()); + assertSame(ChronoUnit.SECONDS, SECONDS.toChronoUnit()); + assertSame(ChronoUnit.MINUTES, MINUTES.toChronoUnit()); + assertSame(ChronoUnit.HOURS, HOURS.toChronoUnit()); + assertSame(ChronoUnit.DAYS, DAYS.toChronoUnit()); + + // Every TimeUnit has a defined ChronoUnit equivalent + for (TimeUnit x : TimeUnit.values()) + assertSame(x, TimeUnit.of(x.toChronoUnit())); + } + + /** + * tests for TimeUnit.of(ChronoUnit). + */ + public void testTimeUnitOf() throws Exception { + assertSame(NANOSECONDS, TimeUnit.of(ChronoUnit.NANOS)); + assertSame(MICROSECONDS, TimeUnit.of(ChronoUnit.MICROS)); + assertSame(MILLISECONDS, TimeUnit.of(ChronoUnit.MILLIS)); + assertSame(SECONDS, TimeUnit.of(ChronoUnit.SECONDS)); + assertSame(MINUTES, TimeUnit.of(ChronoUnit.MINUTES)); + assertSame(HOURS, TimeUnit.of(ChronoUnit.HOURS)); + assertSame(DAYS, TimeUnit.of(ChronoUnit.DAYS)); + + assertThrows(NullPointerException.class, + () -> TimeUnit.of((ChronoUnit)null)); + + // ChronoUnits either round trip to their TimeUnit + // equivalents, or throw IllegalArgumentException. + for (ChronoUnit cu : ChronoUnit.values()) { + final TimeUnit tu; + try { + tu = TimeUnit.of(cu); + } catch (IllegalArgumentException acceptable) { + continue; + } + assertSame(cu, tu.toChronoUnit()); + } + } + +} diff --git a/jdk/test/java/util/concurrent/tck/TimeUnitTest.java b/jdk/test/java/util/concurrent/tck/TimeUnitTest.java index 30f955978d8..437b49b50ed 100644 --- a/jdk/test/java/util/concurrent/tck/TimeUnitTest.java +++ b/jdk/test/java/util/concurrent/tck/TimeUnitTest.java @@ -41,7 +41,6 @@ import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; -import java.time.temporal.ChronoUnit; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -124,6 +123,15 @@ public class TimeUnitTest extends JSR166TestCase { assertEquals(t, NANOSECONDS.convert(t, NANOSECONDS)); } + + for (TimeUnit x : TimeUnit.values()) { + long[] zs = { + 0, 1, -1, + Integer.MAX_VALUE, Integer.MIN_VALUE, + Long.MAX_VALUE, Long.MIN_VALUE, + }; + for (long z : zs) assertEquals(z, x.convert(z, x)); + } } /** @@ -308,6 +316,27 @@ public class TimeUnitTest extends JSR166TestCase { NANOSECONDS.convert(Long.MAX_VALUE / 2, DAYS)); assertEquals(Long.MIN_VALUE, NANOSECONDS.convert(-Long.MAX_VALUE / 4, DAYS)); + + for (TimeUnit x : TimeUnit.values()) + for (TimeUnit y : TimeUnit.values()) { + long ratio = x.toNanos(1) / y.toNanos(1); + if (ratio >= 1) { + assertEquals(ratio, y.convert(1, x)); + assertEquals(1, x.convert(ratio, y)); + long max = Long.MAX_VALUE/ratio; + assertEquals(max * ratio, y.convert(max, x)); + assertEquals(-max * ratio, y.convert(-max, x)); + assertEquals(max, x.convert(max * ratio, y)); + assertEquals(-max, x.convert(-max * ratio, y)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, y.convert(max + 1, x)); + assertEquals(Long.MIN_VALUE, y.convert(-max - 1, x)); + assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE + 1, x)); + } + assertEquals(Long.MAX_VALUE, y.convert(Long.MAX_VALUE, x)); + assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE, x)); + } + } } /** @@ -319,6 +348,146 @@ public class TimeUnitTest extends JSR166TestCase { MILLISECONDS.toNanos(Long.MAX_VALUE / 2)); assertEquals(Long.MIN_VALUE, MILLISECONDS.toNanos(-Long.MAX_VALUE / 3)); + + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / NANOSECONDS.toNanos(1); + if (ratio >= 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toNanos(z)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toNanos(max + 1)); + assertEquals(Long.MIN_VALUE, x.toNanos(-max - 1)); + assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE + 1)); + } + assertEquals(Long.MAX_VALUE, x.toNanos(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE)); + if (max < Integer.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toNanos(Integer.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toNanos(Integer.MIN_VALUE)); + } + } + } + } + + /** + * toMicros saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToMicrosSaturate() { + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / MICROSECONDS.toNanos(1); + if (ratio >= 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toMicros(z)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toMicros(max + 1)); + assertEquals(Long.MIN_VALUE, x.toMicros(-max - 1)); + assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE + 1)); + } + assertEquals(Long.MAX_VALUE, x.toMicros(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE)); + if (max < Integer.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toMicros(Integer.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMicros(Integer.MIN_VALUE)); + } + } + } + } + + /** + * toMillis saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToMillisSaturate() { + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / MILLISECONDS.toNanos(1); + if (ratio >= 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toMillis(z)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toMillis(max + 1)); + assertEquals(Long.MIN_VALUE, x.toMillis(-max - 1)); + assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE + 1)); + } + assertEquals(Long.MAX_VALUE, x.toMillis(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE)); + if (max < Integer.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toMillis(Integer.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMillis(Integer.MIN_VALUE)); + } + } + } + } + + /** + * toSeconds saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToSecondsSaturate() { + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / SECONDS.toNanos(1); + if (ratio >= 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toSeconds(z)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toSeconds(max + 1)); + assertEquals(Long.MIN_VALUE, x.toSeconds(-max - 1)); + assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE + 1)); + } + assertEquals(Long.MAX_VALUE, x.toSeconds(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE)); + if (max < Integer.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toSeconds(Integer.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toSeconds(Integer.MIN_VALUE)); + } + } + } + } + + /** + * toMinutes saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToMinutesSaturate() { + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / MINUTES.toNanos(1); + if (ratio > 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toMinutes(z)); + assertEquals(Long.MAX_VALUE, x.toMinutes(max + 1)); + assertEquals(Long.MIN_VALUE, x.toMinutes(-max - 1)); + assertEquals(Long.MAX_VALUE, x.toMinutes(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE)); + assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE + 1)); + } + } + } + + /** + * toHours saturates positive too-large values to Long.MAX_VALUE + * and negative to LONG.MIN_VALUE + */ + public void testToHoursSaturate() { + for (TimeUnit x : TimeUnit.values()) { + long ratio = x.toNanos(1) / HOURS.toNanos(1); + if (ratio >= 1) { + long max = Long.MAX_VALUE/ratio; + for (long z : new long[] {0, 1, -1, max, -max}) + assertEquals(z * ratio, x.toHours(z)); + if (max < Long.MAX_VALUE) { + assertEquals(Long.MAX_VALUE, x.toHours(max + 1)); + assertEquals(Long.MIN_VALUE, x.toHours(-max - 1)); + assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE + 1)); + } + assertEquals(Long.MAX_VALUE, x.toHours(Long.MAX_VALUE)); + assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE)); + } + } } /** @@ -461,49 +630,4 @@ public class TimeUnitTest extends JSR166TestCase { assertSame(x, serialClone(x)); } - /** - * tests for toChronoUnit. - */ - public void testToChronoUnit() throws Exception { - assertSame(ChronoUnit.NANOS, NANOSECONDS.toChronoUnit()); - assertSame(ChronoUnit.MICROS, MICROSECONDS.toChronoUnit()); - assertSame(ChronoUnit.MILLIS, MILLISECONDS.toChronoUnit()); - assertSame(ChronoUnit.SECONDS, SECONDS.toChronoUnit()); - assertSame(ChronoUnit.MINUTES, MINUTES.toChronoUnit()); - assertSame(ChronoUnit.HOURS, HOURS.toChronoUnit()); - assertSame(ChronoUnit.DAYS, DAYS.toChronoUnit()); - - // Every TimeUnit has a defined ChronoUnit equivalent - for (TimeUnit x : TimeUnit.values()) - assertSame(x, TimeUnit.of(x.toChronoUnit())); - } - - /** - * tests for TimeUnit.of(ChronoUnit). - */ - public void testTimeUnitOf() throws Exception { - assertSame(NANOSECONDS, TimeUnit.of(ChronoUnit.NANOS)); - assertSame(MICROSECONDS, TimeUnit.of(ChronoUnit.MICROS)); - assertSame(MILLISECONDS, TimeUnit.of(ChronoUnit.MILLIS)); - assertSame(SECONDS, TimeUnit.of(ChronoUnit.SECONDS)); - assertSame(MINUTES, TimeUnit.of(ChronoUnit.MINUTES)); - assertSame(HOURS, TimeUnit.of(ChronoUnit.HOURS)); - assertSame(DAYS, TimeUnit.of(ChronoUnit.DAYS)); - - assertThrows(NullPointerException.class, - () -> TimeUnit.of((ChronoUnit)null)); - - // ChronoUnits either round trip to their TimeUnit - // equivalents, or throw IllegalArgumentException. - for (ChronoUnit cu : ChronoUnit.values()) { - final TimeUnit tu; - try { - tu = TimeUnit.of(cu); - } catch (IllegalArgumentException acceptable) { - continue; - } - assertSame(cu, tu.toChronoUnit()); - } - } - } From 63cdcb2f4bec8e0b78b6a48713ec5ac57b7237a8 Mon Sep 17 00:00:00 2001 From: Rachna Goel Date: Mon, 28 Mar 2016 12:36:33 +0530 Subject: [PATCH 03/54] 8150432: LocaleProviders.sh fails Updated Windows 10 kernel name. Reviewed-by: okutsu --- jdk/test/java/util/Locale/LocaleProviders.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/util/Locale/LocaleProviders.sh b/jdk/test/java/util/Locale/LocaleProviders.sh index f90a66fd1e9..4905173f707 100644 --- a/jdk/test/java/util/Locale/LocaleProviders.sh +++ b/jdk/test/java/util/Locale/LocaleProviders.sh @@ -25,6 +25,7 @@ # @test # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8008577 # 8010666 8013086 8013233 8013903 8015960 8028771 8054482 8062006 + 8150432 # @summary tests for "java.locale.providers" system property # @modules java.base/sun.util.locale # java.base/sun.util.locale.provider @@ -168,7 +169,7 @@ case "$OS" in PARAM1=HOST fi ;; - CYGWIN_NT-6* | Darwin ) + CYGWIN_NT-6* | CYGWIN_NT-10* | Darwin ) PARAM1=HOST ;; * ) From 93169df5132b6767930a8b98526c5ff5b1f387b9 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 28 Mar 2016 23:05:01 +0530 Subject: [PATCH 04/54] 8152533: ant octane target fails with "Unable to load a script engine manager (org.apache.bsf.BSFManager or javax.script.ScriptEngineManager)" Reviewed-by: jlaskey --- nashorn/buildtools/nashorntask/README | 1 + nashorn/buildtools/nashorntask/build.xml | 57 ++++++++++++++ .../buildtools/nashorntask/project.properties | 40 ++++++++++ .../src/jdk/nashorn/ant/NashornTask.java | 76 +++++++++++++++++++ nashorn/make/build-benchmark.xml | 30 ++++---- nashorn/make/project.properties | 5 +- 6 files changed, 190 insertions(+), 19 deletions(-) create mode 100644 nashorn/buildtools/nashorntask/README create mode 100644 nashorn/buildtools/nashorntask/build.xml create mode 100644 nashorn/buildtools/nashorntask/project.properties create mode 100644 nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java diff --git a/nashorn/buildtools/nashorntask/README b/nashorn/buildtools/nashorntask/README new file mode 100644 index 00000000000..569250190ef --- /dev/null +++ b/nashorn/buildtools/nashorntask/README @@ -0,0 +1 @@ +This project implements an ant task to run Nashorn scripts from ant projects. diff --git a/nashorn/buildtools/nashorntask/build.xml b/nashorn/buildtools/nashorntask/build.xml new file mode 100644 index 00000000000..612d39db769 --- /dev/null +++ b/nashorn/buildtools/nashorntask/build.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/buildtools/nashorntask/project.properties b/nashorn/buildtools/nashorntask/project.properties new file mode 100644 index 00000000000..dde10f7b03c --- /dev/null +++ b/nashorn/buildtools/nashorntask/project.properties @@ -0,0 +1,40 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +application.title=nashorntask + +# source and target levels +build.compiler=modern +javac.source=1.8 +javac.target=1.8 + +build.classes.dir=${build.dir}/classes + +# This directory is removed when the project is cleaned: +build.dir=build +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/nashorntask.jar +dist.javadoc.dir=${dist.dir}/javadoc + +javac.debug=true +src.dir=src diff --git a/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java b/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java new file mode 100644 index 00000000000..c417f731d1a --- /dev/null +++ b/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.ant; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.BuildException; + +/** + * This class implements an ant task to evaluate nashorn scripts + * from ant projects. + */ +public final class NashornTask extends Task { + // Underlying nashorn script engine + private final ScriptEngine engine; + // the current ant project + private Project project; + // the script evaluated by this task + private String script; + + public NashornTask() { + final ScriptEngineManager m = new ScriptEngineManager(); + this.engine = m.getEngineByName("nashorn"); + } + + @Override + public void setProject(Project proj) { + this.project = proj; + } + + // set the script to be evaluated + public void addText(String text) { + this.script = text; + } + + @Override + public void execute() { + // expose project as "project" variable + engine.put("project", project); + // expose this task as "self" variable + engine.put("self", this); + + // evaluate specified script + try { + engine.eval(script); + } catch (final ScriptException se) { + throw new BuildException(se); + } + } +} diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml index cda125367e3..9bc7b4d893e 100644 --- a/nashorn/make/build-benchmark.xml +++ b/nashorn/make/build-benchmark.xml @@ -217,14 +217,20 @@ + + + + + - + - + ]]> @@ -278,14 +284,8 @@ --> - - + + @@ -318,9 +318,7 @@ - + fork="true"> @@ -391,9 +389,7 @@ - + fork="true"> diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 9b4bdbd2be4..16b809af64c 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -47,14 +47,15 @@ build.classes.dir=${build.dir}/classes build.zip=${build.dir}/nashorn.zip build.gzip=${build.dir}/nashorn.tar.gz +# project directory of ant task +nashorntask.dir=buildtools/nashorntask + # nashorn Shell tool nashorn.shell.tool=jdk.nashorn.tools.Shell # nasgen tool nasgen.tool=jdk.nashorn.internal.tools.nasgen.Main -nasgen.module.imports=\ - nasgen.module.imports=\ java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED,\ java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED From 996686aae01210139d606afd0340beabea3c146c Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Mon, 28 Mar 2016 22:25:32 +0200 Subject: [PATCH 05/54] 8152733: Avoid creating Manifest when checking for Multi-Release attribute Co-authored-by: Steve Drach Reviewed-by: psandoz, alanb --- .../share/classes/java/util/jar/JarFile.java | 195 ++++++++++-------- .../util/jar/JarFile/MultiReleaseJarAPI.java | 4 + 2 files changed, 113 insertions(+), 86 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java index b3bbced134c..7f5726e3656 100644 --- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java @@ -28,7 +28,6 @@ package java.util.jar; import java.io.*; import java.lang.ref.SoftReference; import java.net.URL; -import java.security.PrivilegedAction; import java.util.*; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -38,11 +37,10 @@ import java.security.cert.Certificate; import java.security.AccessController; import java.security.CodeSource; import jdk.internal.misc.SharedSecrets; +import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.security.util.SignatureFileVerifier; -import static java.util.jar.Attributes.Name.MULTI_RELEASE; - /** * The {@code JarFile} class is used to read the contents of a jar file * from any file that can be opened with {@code java.io.RandomAccessFile}. @@ -144,8 +142,9 @@ class JarFile extends ZipFile { private final int version; private boolean notVersioned; private final boolean runtimeVersioned; + private boolean isMultiRelease; // is jar multi-release? - // indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true) + // indicates if Class-Path attribute present private boolean hasClassPathAttribute; // true if manifest checked for special attributes private volatile boolean hasCheckedSpecialAttributes; @@ -155,24 +154,18 @@ class JarFile extends ZipFile { SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl()); BASE_VERSION = 8; // one less than lowest version for versioned entries - RUNTIME_VERSION = AccessController.doPrivileged( - new PrivilegedAction() { - public Integer run() { - Integer v = jdk.Version.current().major(); - Integer i = Integer.getInteger("jdk.util.jar.version", v); - i = i < 0 ? 0 : i; - return i > v ? v : i; - } - } - ); - String multi_release = AccessController.doPrivileged( - new PrivilegedAction() { - public String run() { - return System.getProperty("jdk.util.jar.enableMultiRelease", "true"); - } - } - ); - switch (multi_release) { + int runtimeVersion = jdk.Version.current().major(); + String jarVersion = AccessController.doPrivileged( + new GetPropertyAction("jdk.util.jar.version")); + if (jarVersion != null) { + int jarVer = Integer.parseInt(jarVersion); + runtimeVersion = (jarVer > runtimeVersion) + ? runtimeVersion : Math.max(jarVer, 0); + } + RUNTIME_VERSION = runtimeVersion; + String enableMultiRelease = AccessController.doPrivileged( + new GetPropertyAction("jdk.util.jar.enableMultiRelease", "true")); + switch (enableMultiRelease) { case "true": default: MULTI_RELEASE_ENABLED = true; @@ -353,8 +346,14 @@ class JarFile extends ZipFile { Objects.requireNonNull(version); this.verify = verify; // version applies to multi-release jar files, ignored for regular jar files - this.version = MULTI_RELEASE_FORCED ? RUNTIME_VERSION : version.value(); + if (MULTI_RELEASE_FORCED) { + this.version = RUNTIME_VERSION; + version = Release.RUNTIME; + } else { + this.version = version.value(); + } this.runtimeVersioned = version == Release.RUNTIME; + assert runtimeVersionExists(); } @@ -392,35 +391,18 @@ class JarFile extends ZipFile { * @since 9 */ public final boolean isMultiRelease() { - // do not call this code in a constructor because some subclasses use - // lazy loading of manifest so it won't be available at construction time - if (MULTI_RELEASE_ENABLED) { - // Doubled-checked locking pattern - Boolean result = isMultiRelease; - if (result == null) { - synchronized (this) { - result = isMultiRelease; - if (result == null) { - Manifest man = null; - try { - man = getManifest(); - } catch (IOException e) { - //Ignored, manifest cannot be read - } - isMultiRelease = result = (man != null) - && man.getMainAttributes().containsKey(MULTI_RELEASE) - ? Boolean.TRUE : Boolean.FALSE; - } - } - } - return result == Boolean.TRUE; - } else { - return false; + if (isMultiRelease) { + return true; } + if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) { + try { + checkForSpecialAttributes(); + } catch (IOException io) { + isMultiRelease = false; + } + } + return isMultiRelease; } - // the following field, isMultiRelease, should only be used in the method - // isMultiRelease(), like a static local - private volatile Boolean isMultiRelease; // is jar multi-release? /** * Returns the jar file manifest, or {@code null} if none. @@ -905,26 +887,44 @@ class JarFile extends ZipFile { } // Statics for hand-coded Boyer-Moore search - private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'}; - // The bad character shift for "class-path" - private static final int[] CLASSPATH_LASTOCC; - // The good suffix shift for "class-path" - private static final int[] CLASSPATH_OPTOSFT; + private static final byte[] CLASSPATH_CHARS = + {'C','L','A','S','S','-','P','A','T','H', ':', ' '}; + + // The bad character shift for "class-path:" + private static final byte[] CLASSPATH_LASTOCC; + + private static final byte[] MULTIRELEASE_CHARS = + {'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':', ' '}; + + // The bad character shift for "multi-release: " + private static final byte[] MULTIRELEASE_LASTOCC; static { - CLASSPATH_LASTOCC = new int[128]; - CLASSPATH_OPTOSFT = new int[10]; - CLASSPATH_LASTOCC[(int)'c'] = 1; - CLASSPATH_LASTOCC[(int)'l'] = 2; - CLASSPATH_LASTOCC[(int)'s'] = 5; - CLASSPATH_LASTOCC[(int)'-'] = 6; - CLASSPATH_LASTOCC[(int)'p'] = 7; - CLASSPATH_LASTOCC[(int)'a'] = 8; - CLASSPATH_LASTOCC[(int)'t'] = 9; - CLASSPATH_LASTOCC[(int)'h'] = 10; - for (int i=0; i<9; i++) - CLASSPATH_OPTOSFT[i] = 10; - CLASSPATH_OPTOSFT[9]=1; + CLASSPATH_LASTOCC = new byte[64]; + CLASSPATH_LASTOCC[(int)'C' - 32] = 1; + CLASSPATH_LASTOCC[(int)'L' - 32] = 2; + CLASSPATH_LASTOCC[(int)'S' - 32] = 5; + CLASSPATH_LASTOCC[(int)'-' - 32] = 6; + CLASSPATH_LASTOCC[(int)'P' - 32] = 7; + CLASSPATH_LASTOCC[(int)'A' - 32] = 8; + CLASSPATH_LASTOCC[(int)'T' - 32] = 9; + CLASSPATH_LASTOCC[(int)'H' - 32] = 10; + CLASSPATH_LASTOCC[(int)':' - 32] = 11; + CLASSPATH_LASTOCC[(int)' ' - 32] = 12; + + MULTIRELEASE_LASTOCC = new byte[64]; + MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1; + MULTIRELEASE_LASTOCC[(int)'U' - 32] = 2; + MULTIRELEASE_LASTOCC[(int)'T' - 32] = 4; + MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5; + MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6; + MULTIRELEASE_LASTOCC[(int)'R' - 32] = 7; + MULTIRELEASE_LASTOCC[(int)'L' - 32] = 9; + MULTIRELEASE_LASTOCC[(int)'A' - 32] = 11; + MULTIRELEASE_LASTOCC[(int)'S' - 32] = 12; + MULTIRELEASE_LASTOCC[(int)'E' - 32] = 13; + MULTIRELEASE_LASTOCC[(int)':' - 32] = 14; + MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15; } private JarEntry getManEntry() { @@ -962,22 +962,33 @@ class JarFile extends ZipFile { /** * Returns true if the pattern {@code src} is found in {@code b}. - * The {@code lastOcc} and {@code optoSft} arrays are the precomputed - * bad character and good suffix shifts. + * The {@code lastOcc} array is the precomputed bad character shifts. + * Since there are no repeated substring in our search strings, + * the good suffix shifts can be replaced with a comparison. */ - private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) { + private boolean match(byte[] src, byte[] b, byte[] lastOcc) { int len = src.length; int last = b.length - len; int i = 0; next: - while (i<=last) { - for (int j=(len-1); j>=0; j--) { - char c = (char) b[i+j]; - c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c; - if (c != src[j]) { - i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]); + while (i <= last) { + for (int j = (len - 1); j >= 0; j--) { + byte c = b[i + j]; + if (c >= ' ' && c <= 'z') { + if (c >= 'a') c -= 32; // Canonicalize + + if (c != src[j]) { + // no match + int goodShift = (j < len - 1) ? len : 1; + int badShift = lastOcc[c - 32]; + i += Math.max(j + 1 - badShift, goodShift); + continue next; + } + } else { + // no match, character not valid for name + i += len; continue next; - } + } } return true; } @@ -986,17 +997,29 @@ class JarFile extends ZipFile { /** * On first invocation, check if the JAR file has the Class-Path - * attribute. A no-op on subsequent calls. + * and the Multi-Release attribute. A no-op on subsequent calls. */ private void checkForSpecialAttributes() throws IOException { - if (hasCheckedSpecialAttributes) return; - JarEntry manEntry = getManEntry(); - if (manEntry != null) { - byte[] b = getBytes(manEntry); - if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT)) - hasClassPathAttribute = true; + if (hasCheckedSpecialAttributes) { + return; + } + synchronized (this) { + if (hasCheckedSpecialAttributes) { + return; + } + JarEntry manEntry = getManEntry(); + if (manEntry != null) { + byte[] b = getBytes(manEntry); + hasClassPathAttribute = match(CLASSPATH_CHARS, b, + CLASSPATH_LASTOCC); + // is this a multi-release jar file + if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) { + isMultiRelease = match(MULTIRELEASE_CHARS, b, + MULTIRELEASE_LASTOCC); + } + } + hasCheckedSpecialAttributes = true; } - hasCheckedSpecialAttributes = true; } private synchronized void ensureInitialization() { diff --git a/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java b/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java index a520d316a58..548b4bace19 100644 --- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java +++ b/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java @@ -83,6 +83,10 @@ public class MultiReleaseJarAPI { } try (JarFile jf = new JarFile(multirelease)) { + Assert.assertFalse(jf.isMultiRelease()); + } + + try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) { Assert.assertTrue(jf.isMultiRelease()); } } From b853c8f575d4691677b4faf8f8a5f55ec123f6a8 Mon Sep 17 00:00:00 2001 From: Amy Lu Date: Tue, 29 Mar 2016 10:47:03 +0800 Subject: [PATCH 06/54] 8152873: java/util/Locale/LocaleProviders.sh fails after JDK-8150432 Reviewed-by: darcy --- jdk/test/java/util/Locale/LocaleProviders.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/util/Locale/LocaleProviders.sh b/jdk/test/java/util/Locale/LocaleProviders.sh index 4905173f707..cddb4274805 100644 --- a/jdk/test/java/util/Locale/LocaleProviders.sh +++ b/jdk/test/java/util/Locale/LocaleProviders.sh @@ -25,7 +25,7 @@ # @test # @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8008577 # 8010666 8013086 8013233 8013903 8015960 8028771 8054482 8062006 - 8150432 +# 8150432 # @summary tests for "java.locale.providers" system property # @modules java.base/sun.util.locale # java.base/sun.util.locale.provider From b09c81ce39944e606cb3a6ddebf8d8557644f4b5 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Tue, 29 Mar 2016 18:04:41 +0900 Subject: [PATCH 07/54] 8152077: (cal) Calendar.roll does not always roll the hours during daylight savings Reviewed-by: peytoia --- .../classes/java/util/GregorianCalendar.java | 48 +++---- jdk/test/java/util/Calendar/Bug8152077.java | 135 ++++++++++++++++++ 2 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 jdk/test/java/util/Calendar/Bug8152077.java diff --git a/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java b/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java index b731b142843..d244e7d37b2 100644 --- a/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java +++ b/jdk/src/java.base/share/classes/java/util/GregorianCalendar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -1189,37 +1189,33 @@ public class GregorianCalendar extends Calendar { case HOUR: case HOUR_OF_DAY: { - int unit = max + 1; // 12 or 24 hours - int h = internalGet(field); - int nh = (h + amount) % unit; - if (nh < 0) { - nh += unit; + int rolledValue = getRolledValue(internalGet(field), amount, min, max); + int hourOfDay = rolledValue; + if (field == HOUR && internalGet(AM_PM) == PM) { + hourOfDay += 12; } - time += ONE_HOUR * (nh - h); - // The day might have changed, which could happen if - // the daylight saving time transition brings it to - // the next day, although it's very unlikely. But we - // have to make sure not to change the larger fields. + // Create the current date/time value to perform wall-clock-based + // roll. CalendarDate d = calsys.getCalendarDate(time, getZone()); - if (internalGet(DAY_OF_MONTH) != d.getDayOfMonth()) { - d.setDate(internalGet(YEAR), - internalGet(MONTH) + 1, - internalGet(DAY_OF_MONTH)); - if (field == HOUR) { - assert (internalGet(AM_PM) == PM); - d.addHours(+12); // restore PM + d.setHours(hourOfDay); + time = calsys.getTime(d); + + // If we stay on the same wall-clock time, try the next or previous hour. + if (internalGet(HOUR_OF_DAY) == d.getHours()) { + hourOfDay = getRolledValue(rolledValue, amount > 0 ? +1 : -1, min, max); + if (field == HOUR && internalGet(AM_PM) == PM) { + hourOfDay += 12; } + d.setHours(hourOfDay); time = calsys.getTime(d); } - int hourOfDay = d.getHours(); - internalSet(field, hourOfDay % unit); - if (field == HOUR) { - internalSet(HOUR_OF_DAY, hourOfDay); - } else { - internalSet(AM_PM, hourOfDay / 12); - internalSet(HOUR, hourOfDay % 12); - } + // Get the new hourOfDay value which might have changed due to a DST transition. + hourOfDay = d.getHours(); + // Update the hour related fields + internalSet(HOUR_OF_DAY, hourOfDay); + internalSet(AM_PM, hourOfDay / 12); + internalSet(HOUR, hourOfDay % 12); // Time zone offset and/or daylight saving might have changed. int zoneOffset = d.getZoneOffset(); diff --git a/jdk/test/java/util/Calendar/Bug8152077.java b/jdk/test/java/util/Calendar/Bug8152077.java new file mode 100644 index 00000000000..25afc5632eb --- /dev/null +++ b/jdk/test/java/util/Calendar/Bug8152077.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8152077 + * @summary Make sure that roll() with HOUR/HOUR_OF_DAY works around standard/daylight + * time transitions + */ + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import static java.util.Calendar.*; + +public class Bug8152077 { + private static final TimeZone LA = TimeZone.getTimeZone("America/Los_Angeles"); + private static final TimeZone BR = TimeZone.getTimeZone("America/Sao_Paulo"); + + private static final int[] ALLDAY_HOURS = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 + }; + private static final int[] AM_HOURS = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + }; + private static final int[] PM_HOURS = { // in 24-hour clock + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 + }; + + private static int errors; + + public static void main(String[] args) { + TimeZone initialTz = TimeZone.getDefault(); + try { + testRoll(LA, new int[] { 2016, MARCH, 13 }, + new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }); + testRoll(LA, new int[] { 2016, MARCH, 13 }, + new int[] { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); + testRoll(LA, new int[] { 2016, MARCH, 13 }, PM_HOURS); + + testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, ALLDAY_HOURS); + testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, AM_HOURS); + testRoll(LA, new int[] { 2016, NOVEMBER, 6 }, PM_HOURS); + + testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, ALLDAY_HOURS); + testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, AM_HOURS); + testRoll(BR, new int[] { 2016, FEBRUARY, 21 }, PM_HOURS); + + testRoll(BR, new int[] { 2016, OCTOBER, 15 }, ALLDAY_HOURS); + testRoll(BR, new int[] { 2016, OCTOBER, 15 }, PM_HOURS); + testRoll(BR, new int[] { 2016, OCTOBER, 16 }, + new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }); + testRoll(BR, new int[] { 2016, OCTOBER, 16 }, + new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); + testRoll(BR, new int[] { 2016, OCTOBER, 16 }, PM_HOURS); + } finally { + TimeZone.setDefault(initialTz); + } + if (errors > 0) { + throw new RuntimeException("Test failed"); + } + } + + private static void testRoll(TimeZone tz, int[] params, int[] sequence) { + TimeZone.setDefault(tz); + for (int i = 0; i < sequence.length; i++) { + testRoll(+1, params, sequence, i); + testRoll(-1, params, sequence, i); + } + } + + // amount must be 1 or -1. + private static void testRoll(int amount, int[] params, int[] sequence, int startIndex) { + int year = params[0]; + int month = params[1]; + int dayOfMonth = params[2]; + int hourOfDay = sequence[startIndex]; + Calendar cal = new GregorianCalendar(year, month, dayOfMonth, + hourOfDay, 0, 0); + int ampm = cal.get(AM_PM); + + int length = sequence.length; + int count = length * 2; + int field = (length > 12) ? HOUR_OF_DAY : HOUR; + + System.out.printf("roll(%s, %2d) starting from %s%n", + (field == HOUR) ? "HOUR" : "HOUR_OF_DAY", amount, cal.getTime()); + for (int i = 0; i < count; i++) { + int index = (amount > 0) ? (startIndex + i + 1) % length + : Math.floorMod(startIndex - i - 1, length); + int expected = sequence[index]; + if (field == HOUR) { + expected %= 12; + } + cal.roll(field, amount); + int value = cal.get(field); + if (value != expected) { + System.out.println("Unexpected field value: got=" + value + + ", expected=" + expected); + errors++; + } + if (cal.get(DAY_OF_MONTH) != dayOfMonth) { + System.out.println("DAY_OF_MONTH changed: " + dayOfMonth + + " to " + cal.get(DAY_OF_MONTH)); + } + if (field == HOUR && cal.get(AM_PM) != ampm) { + System.out.println("AM_PM changed: " + ampm + " to " + cal.get(AM_PM)); + errors++; + } + } + } +} From 3312808cdbedf4bf41588cc45cea447d578574e2 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Tue, 29 Mar 2016 18:27:33 +0200 Subject: [PATCH 08/54] 8152951: Avoid calculating the reverse of StringConcatFactory$Recipe elements Reviewed-by: shade, vlivanov --- .../java/lang/invoke/StringConcatFactory.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 75776cde90c..f94746a71fa 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -255,7 +255,6 @@ public final class StringConcatFactory { */ private static final class Recipe { private final List elements; - private final List elementsRev; public Recipe(String src, Object[] constants) { List el = new ArrayList<>(); @@ -294,19 +293,13 @@ public final class StringConcatFactory { el.add(new RecipeElement(acc.toString())); } - elements = new ArrayList<>(el); - Collections.reverse(el); - elementsRev = el; + elements = el; } - public Collection getElements() { + public List getElements() { return elements; } - public Collection getElementsReversed() { - return elementsRev; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -1310,7 +1303,9 @@ public final class StringConcatFactory { // Compose append calls. This is done in reverse because the application order is // reverse as well. - for (RecipeElement el : recipe.getElementsReversed()) { + List elements = recipe.getElements(); + for (int i = elements.size() - 1; i >= 0; i--) { + RecipeElement el = elements.get(i); MethodHandle appender; switch (el.getTag()) { case CONST: { From db8417dface58b2fb7f8894bbb37ab13aef65c47 Mon Sep 17 00:00:00 2001 From: Lana Steuck Date: Thu, 31 Mar 2016 01:13:33 -0700 Subject: [PATCH 09/54] Added tag jdk-9+112 for changeset bf40906bf49d --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index a50a63bf2ff..9be12ab163f 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -354,3 +354,4 @@ fd18a155ad22f62e06a9b74850ab8609d415c752 jdk-9+108 f5991c73ed73b9a355a090b65c8d7fb9a1901f89 jdk-9+109 9b4c916633f8d61509a3dc6175efdf185b421343 jdk-9+110 9adfb22ff08f2e82c7801b272607cd685976dbb1 jdk-9+111 +3d4117c36559b344a73f786d39cc7626b4d8e2c0 jdk-9+112 From 6d6d60aa9a32e994151d09cb2c571e029b630aeb Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 31 Mar 2016 11:50:26 -0700 Subject: [PATCH 10/54] 8153211: Convert build tool to use the new -XaddExports syntax in bootcycle build Reviewed-by: alanb --- langtools/make/gendata/Gendata-jdk.compiler.gmk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/langtools/make/gendata/Gendata-jdk.compiler.gmk b/langtools/make/gendata/Gendata-jdk.compiler.gmk index 613e7133a05..d0eb92e600e 100644 --- a/langtools/make/gendata/Gendata-jdk.compiler.gmk +++ b/langtools/make/gendata/Gendata-jdk.compiler.gmk @@ -40,7 +40,10 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ )) ifeq ($(BOOT_JDK_MODULAR), true) - COMPILECREATESYMBOLS_ADD_EXPORTS := -XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED,jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED,jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED + COMPILECREATESYMBOLS_ADD_EXPORTS := \ + -XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -XaddExports:jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \ + -XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED endif $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \ From 332e2c9a68f49a43456ef5513125c2c2da2652d1 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 31 Mar 2016 17:25:58 -0400 Subject: [PATCH 11/54] 8150733: NPE when compiling module-info.java with a class declaration in a non-module mode Reviewed-by: jjg --- .../com/sun/tools/javac/tree/TreeInfo.java | 5 +- .../modules/NPECompilingModuleInfoTest.java | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index e22fb6446d9..a032e91fdae 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, 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 @@ -1152,7 +1152,8 @@ public class TreeInfo { } public static boolean isModuleInfo(JCCompilationUnit tree) { - return tree.sourcefile.isNameCompatible("module-info", JavaFileObject.Kind.SOURCE); + return tree.sourcefile.isNameCompatible("module-info", JavaFileObject.Kind.SOURCE) + && tree.defs.nonEmpty() && tree.defs.head.hasTag(MODULEDEF); } public static JCModuleDecl getModule(JCCompilationUnit t) { diff --git a/langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java b/langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java new file mode 100644 index 00000000000..34d16b3c427 --- /dev/null +++ b/langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8150733 + * @summary NPE when compiling module-info.java with a class declaration in a non-module mode + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.jdeps/com.sun.tools.javap + * @build ToolBox ModuleTestBase + * @run main NPECompilingModuleInfoTest + */ + +import java.nio.file.Path; + +import com.sun.source.util.JavacTask; + +public class NPECompilingModuleInfoTest extends ModuleTestBase { + public static void main(String... args) throws Exception { + new NPECompilingModuleInfoTest().runTests(); + } + + @Test + void testCompileNoError(Path base) throws Exception { + Path mod = base.resolve("mod"); + tb.writeJavaFiles(mod, "module mod { exports pkg; }"); + Path pkg = mod.resolve("pkg"); + Path customClass = pkg.resolve("module-info.java"); + tb.writeFile(customClass, "package pkg; class C {}"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + tb.new JavacTask() + .outdir(classes) + .files(findJavaFiles(mod)) + .run() + .writeAll() + .getOutputLines(ToolBox.OutputKind.DIRECT); + } +} From 208d93e1106b5561c41394d8775bc0dd814b078a Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 31 Mar 2016 14:56:33 -0700 Subject: [PATCH 12/54] 6818181: Update naming convention annotation processing samples for modules Reviewed-by: jjg --- .../processing/src/CheckNamesProcessor.java | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/langtools/src/sample/share/javac/processing/src/CheckNamesProcessor.java b/langtools/src/sample/share/javac/processing/src/CheckNamesProcessor.java index e15bb7bf12a..e8ecdda02e0 100644 --- a/langtools/src/sample/share/javac/processing/src/CheckNamesProcessor.java +++ b/langtools/src/sample/share/javac/processing/src/CheckNamesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -75,9 +75,6 @@ import static javax.tools.Diagnostic.Kind.*; * * * - * For some notes on how to run an annotation processor inside - * NetBeans, see http://wiki.java.net/bin/view/Netbeans/FaqApt. - * *

Possible Enhancements

*