# HG changeset patch # User duke # Date 1499276587 -7200 # Node ID 4a09f5d30be844ac6f714bdb0f63d8c3c08b9a98 # Parent 8c984568f736b98d7ce4513004dc210a39bb2dd3# Parent ba3dc5355ed19a023e16dc1a24d07200ad9f79f0 Merge diff -r ba3dc5355ed1 -r 4a09f5d30be8 .hgtags-top-repo --- a/.hgtags-top-repo Wed Jul 05 19:42:33 2017 +0200 +++ b/.hgtags-top-repo Wed Jul 05 19:43:07 2017 +0200 @@ -257,3 +257,4 @@ 59f6350295f9681fe5956d8bc889bf341914c6cb jdk9-b12 5800456add07e1a68170a229fb5e27376f8875e5 jdk9-b13 4e3aa9723e9972623e3dafc321b368e7db7e9b3b jdk9-b14 +b114474fb25af4e73cb7219f7c04bd8994da03a5 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 corba/.hgtags --- a/corba/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/corba/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -257,3 +257,4 @@ e212cdcc8c11f0ba5acf6f5ddb596c4c545a93f9 jdk9-b12 088eec4c36f4d7f250fcd19c4969bf698e3d2cdc jdk9-b13 a2b82f863ba95a596da555a4c1b871c404863e7e jdk9-b14 +e54022d0dd92106fff7f7fe670010cd7e6517ee3 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 hotspot/.hgtags --- a/hotspot/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/hotspot/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -417,3 +417,4 @@ 1c383bb39e2849ca62cb763f4e182a29b421d60a jdk9-b12 456ad9c99133803d4e1433124c85a6fd141b9ac9 jdk9-b13 bd333491bb6c012d7b606939406d0fa9a5ac7ffd jdk9-b14 +170f6d733d7aec062f743a6b8c1cce940a7a984a jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 jaxp/.hgtags --- a/jaxp/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/jaxp/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -257,3 +257,4 @@ e88cecf5a21b760ff7d7761c2db6bb8c82bc9f0c jdk9-b12 5eaf717f6e36037a6d3744ffeee0e4c88e64a0d2 jdk9-b13 32b3fc4bc7374a34d52b7f4e2391b4b4b0c084e8 jdk9-b14 +6bad71866c7598587860e0981b0b0e51ec8c0476 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 jaxws/.hgtags --- a/jaxws/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/jaxws/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -260,3 +260,4 @@ 779f8b21c75f83e3918dac8499e4d0ecb3a54ed7 jdk9-b12 3d42204854c9f703e3ccdc8891248e73057713ab jdk9-b13 02e58850b7062825308413d420f2b02c1f25a724 jdk9-b14 +e9780330017a6b464a385356d77e5136f9de8d09 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/.hgtags --- a/jdk/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -257,3 +257,4 @@ 83d9bc20973de232cae45b139fdff8a4549c130f jdk9-b12 c7c8002d02721e02131d104549ebeb8b379fb8d2 jdk9-b13 5c7a17a81afd0906b53ee31d95a3211c96ff6b25 jdk9-b14 +4537360f09fe23ab339ee588747b657feb12d0c8 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/make/CopyIntoClasses.gmk --- a/jdk/make/CopyIntoClasses.gmk Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/make/CopyIntoClasses.gmk Wed Jul 05 19:43:07 2017 +0200 @@ -30,7 +30,6 @@ # These directories should not be copied at all EXCLUDES += \ - com/sun/org/apache/xml/internal/security/resource/schema \ java/awt/doc-files \ java/lang/doc-files \ javax/swing/doc-files \ diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.rng --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.rng Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.xsd --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xenc-schema.xsd Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ - - - - - - ]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.dtd Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.rng --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.rng Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/xmldsig-core-schema.xsd Wed Jul 05 19:42:33 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,318 +0,0 @@ - - - - - - ]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java --- a/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/classes/jdk/internal/util/xml/impl/Parser.java Wed Jul 05 19:43:07 2017 +0200 @@ -2860,14 +2860,25 @@ } else { // Get encoding from BOM or the xml text decl. reader = bom(is.getByteStream(), ' '); + /** + * [#4.3.3] requires BOM for UTF-16, however, it's not uncommon + * that it may be missing. A mature technique exists in Xerces + * to further check for possible UTF-16 encoding + */ + if (reader == null) { + reader = utf16(is.getByteStream()); + } + if (reader == null) { // Encoding is defined by the xml text decl. reader = enc("UTF-8", is.getByteStream()); expenc = xml(reader); - if (expenc.startsWith("UTF-16")) { - panic(FAULT); // UTF-16 must have BOM [#4.3.3] + if (!expenc.equals("UTF-8")) { + if (expenc.startsWith("UTF-16")) { + panic(FAULT); // UTF-16 must have BOM [#4.3.3] + } + reader = enc(expenc, is.getByteStream()); } - reader = enc(expenc, is.getByteStream()); } else { // Encoding is defined by the BOM. xml(reader); @@ -2956,6 +2967,49 @@ } } + + /** + * Using a mature technique from Xerces, this method checks further after + * the bom method above to see if the encoding is UTF-16 + * + * @param is A byte stream of the entity. + * @return a reader, may be null + * @exception Exception is parser specific exception form panic method. + * @exception IOException + */ + private Reader utf16(InputStream is) + throws Exception { + if (mChIdx != 0) { + //The bom method has read ONE byte into the buffer. + byte b0 = (byte)mChars[0]; + if (b0 == 0x00 || b0 == 0x3C) { + int b1 = is.read(); + int b2 = is.read(); + int b3 = is.read(); + if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { + // UTF-16, big-endian, no BOM + mChars[0] = (char)(b1); + mChars[mChIdx++] = (char)(b3); + return new ReaderUTF16(is, 'b'); + } else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { + // UTF-16, little-endian, no BOM + mChars[0] = (char)(b0); + mChars[mChIdx++] = (char)(b2); + return new ReaderUTF16(is, 'l'); + } else { + /**not every InputStream supports reset, so we have to remember + * the state for further parsing + **/ + mChars[0] = (char)(b0); + mChars[mChIdx++] = (char)(b1); + mChars[mChIdx++] = (char)(b2); + mChars[mChIdx++] = (char)(b3); + } + + } + } + return null; + } /** * Parses the xml text declaration. * @@ -2974,17 +3028,17 @@ String enc = "UTF-8"; char ch; int val; - short st; - // Read the xml text declaration into the buffer - if (mChIdx != 0) { - // The bom method have read ONE char into the buffer. - st = (short) ((mChars[0] == '<') ? 1 : -1); - } else { - st = 0; - } + short st = 0; + int byteRead = mChIdx; //number of bytes read prior to entering this method + while (st >= 0 && mChIdx < mChars.length) { - ch = ((val = reader.read()) >= 0) ? (char) val : EOS; - mChars[mChIdx++] = ch; + if (st < byteRead) { + ch = mChars[st]; + } else { + ch = ((val = reader.read()) >= 0) ? (char) val : EOS; + mChars[mChIdx++] = ch; + } + switch (st) { case 0: // read '<' of xml declaration switch (ch) { diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java --- a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Wed Jul 05 19:43:07 2017 +0200 @@ -93,9 +93,9 @@ public Socket accept() throws IOException { synchronized (ssc.blockingLock()) { - if (!ssc.isBound()) - throw new IllegalBlockingModeException(); try { + if (!ssc.isBound()) + throw new NotYetBoundException(); if (timeout == 0) { SocketChannel sc = ssc.accept(); if (sc == null && !ssc.isBlocking()) diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/sun/security/krb5/KdcComm.java --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java Wed Jul 05 19:43:07 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,7 +144,8 @@ try { Config cfg = Config.getInstance(); String temp = cfg.get("libdefaults", "kdc_timeout"); - timeout = parsePositiveIntString(temp); + timeout = parseTimeString(temp); + temp = cfg.get("libdefaults", "max_retries"); max_retries = parsePositiveIntString(temp); temp = cfg.get("libdefaults", "udp_preference_limit"); @@ -426,6 +427,25 @@ } /** + * Parses a time value string. If it ends with "s", parses as seconds. + * Otherwise, parses as milliseconds. + * @param s the time string + * @return the integer value in milliseconds, or -1 if input is null or + * has an invalid format + */ + private static int parseTimeString(String s) { + if (s == null) { + return -1; + } + if (s.endsWith("s")) { + int seconds = parsePositiveIntString(s.substring(0, s.length()-1)); + return (seconds < 0) ? -1 : (seconds*1000); + } else { + return parsePositiveIntString(s); + } + } + + /** * Returns krb5.conf setting of {@code key} for a specific realm, * which can be: * 1. defined in the sub-stanza for the given realm inside [realms], or @@ -446,7 +466,11 @@ try { String value = Config.getInstance().get("realms", realm, key); - temp = parsePositiveIntString(value); + if (key.equals("kdc_timeout")) { + temp = parseTimeString(value); + } else { + temp = parsePositiveIntString(value); + } } catch (Exception exc) { // Ignored, defValue will be picked up } diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/sun/security/smartcardio/CardImpl.java --- a/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Wed Jul 05 19:43:07 2017 +0200 @@ -246,7 +246,7 @@ } checkExclusive(); try { - SCardDisconnect(cardId, (reset ? SCARD_LEAVE_CARD : SCARD_RESET_CARD)); + SCardDisconnect(cardId, (reset ? SCARD_RESET_CARD : SCARD_LEAVE_CARD)); } catch (PCSCException e) { throw new CardException("disconnect() failed", e); } finally { diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/classes/sun/security/tools/jarsigner/Main.java --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java Wed Jul 05 19:43:07 2017 +0200 @@ -1560,8 +1560,7 @@ first = false; } try { - CertPath cp = certificateFactory.generateCertPath(certs); - validator.validate(cp, pkixParameters); + validateCertChain(certs); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -1871,8 +1870,7 @@ printCert("", certChain[0], true, null, true); try { - CertPath cp = certificateFactory.generateCertPath(Arrays.asList(certChain)); - validator.validate(cp, pkixParameters); + validateCertChain(Arrays.asList(certChain)); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -1937,6 +1935,22 @@ System.exit(1); } + void validateCertChain(List certs) throws Exception { + int cpLen = 0; + out: for (; cpLen 0) { + CertPath cp = certificateFactory.generateCertPath( + (cpLen == certs.size())? certs: certs.subList(0, cpLen)); + validator.validate(cp, pkixParameters); + } + } + char[] getPass(String prompt) { System.err.print(prompt); diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/share/native/sun/security/smartcardio/pcsc.c --- a/jdk/src/share/native/sun/security/smartcardio/pcsc.c Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/share/native/sun/security/smartcardio/pcsc.c Wed Jul 05 19:43:07 2017 +0200 @@ -125,7 +125,7 @@ jobjectArray pcsc_multi2jstring(JNIEnv *env, char *spec) { jobjectArray result; jclass stringClass; - char *cp, **tab; + char *cp, **tab = NULL; jstring js; int cnt = 0; @@ -179,7 +179,7 @@ { SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; - LPTSTR mszReaders; + LPTSTR mszReaders = NULL; DWORD size = 0; jobjectArray result; @@ -190,18 +190,20 @@ } dprintf1("-size: %d\n", size); - mszReaders = malloc(size); - if (mszReaders == NULL) { - throwOutOfMemoryError(env, NULL); - return NULL; - } + if (size) { + mszReaders = malloc(size); + if (mszReaders == NULL) { + throwOutOfMemoryError(env, NULL); + return NULL; + } - rv = CALL_SCardListReaders(context, NULL, mszReaders, &size); - if (handleRV(env, rv)) { - free(mszReaders); - return NULL; + rv = CALL_SCardListReaders(context, NULL, mszReaders, &size); + if (handleRV(env, rv)) { + free(mszReaders); + return NULL; + } + dprintf1("-String: %s\n", mszReaders); } - dprintf1("-String: %s\n", mszReaders); result = pcsc_multi2jstring(env, mszReaders); free(mszReaders); @@ -336,7 +338,7 @@ const char *readerName; readerState = calloc(readers, sizeof(SCARD_READERSTATE)); - if (readerState == NULL) { + if (readerState == NULL && readers > 0) { throwOutOfMemoryError(env, NULL); return NULL; } @@ -348,6 +350,10 @@ } for (i = 0; i < readers; i++) { + readerState[i].szReader = NULL; + } + + for (i = 0; i < readers; i++) { jobject jReaderName = (*env)->GetObjectArrayElement(env, jReaderNames, i); if ((*env)->ExceptionCheck(env)) { goto cleanup; @@ -369,9 +375,11 @@ (*env)->DeleteLocalRef(env, jReaderName); } - rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers); - if (handleRV(env, rv)) { - goto cleanup; + if (readers > 0) { + rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers); + if (handleRV(env, rv)) { + goto cleanup; + } } jEventState = (*env)->NewIntArray(env, readers); diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/solaris/classes/java/lang/UNIXProcess.java --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java Wed Jul 05 19:43:07 2017 +0200 @@ -97,6 +97,7 @@ EnumSet.copyOf(Arrays.asList(launchMechanisms)); } + @SuppressWarnings("fallthrough") private String helperPath(String javahome, String osArch) { switch (this) { case SOLARIS: diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c --- a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c Wed Jul 05 19:43:07 2017 +0200 @@ -136,5 +136,9 @@ if ((*env)->ExceptionCheck(env)) { return; } +#ifndef __APPLE__ scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl"); +#else + scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl132"); +#endif // __APPLE__ } diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/ProblemList.txt Wed Jul 05 19:43:07 2017 +0200 @@ -261,6 +261,10 @@ # 8041934 com/sun/jdi/RepStep.java generic-all +# 8044419 +com/sun/jdi/JdbReadTwiceTest.sh generic-all + + ############################################################################ # jdk_util diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java --- a/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java Wed Jul 05 19:43:07 2017 +0200 @@ -33,11 +33,9 @@ import java.util.ArrayList; import java.util.List; import java.nio.file.Files; -import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributeView; -import java.util.stream.Stream; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -163,34 +161,66 @@ tr.assertZero("Should still return 0"); } + private static boolean isWriteableDirectory(Path p) { + if (!Files.isDirectory(p)) { + return false; + } + Path test = p.resolve(Paths.get("test")); + try { + Files.createFile(test); + assertTrue(Files.exists(test)); + return true; + } catch (IOException e) { + assertFalse(Files.exists(test)); + return false; + } finally { + if (Files.exists(test)) { + try { + Files.delete(test); + } catch (IOException e) { + throw new Error(e); + } + } + } + } + @Test public void testDumpDirNotWritable() throws IOException { - if (! Files.getFileStore(Paths.get(".")) - .supportsFileAttributeView(PosixFileAttributeView.class)) { + if (!Files.getFileStore(Paths.get(".")) + .supportsFileAttributeView(PosixFileAttributeView.class)) { // No easy way to setup readonly directory without POSIX // We would like to skip the test with a cause with // throw new SkipException("Posix not supported"); // but jtreg will report failure so we just pass the test // which we can look at if jtreg changed its behavior + System.out.println("WARNING: POSIX is not supported. Skipping testDumpDirNotWritable test."); return; } Files.createDirectory(Paths.get("readOnly"), asFileAttribute(fromString("r-xr-xr-x"))); + try { + if (isWriteableDirectory(Paths.get("readOnly"))) { + // Skipping the test: it's allowed to write into read-only directory + // (e.g. current user is super user). + System.out.println("WARNING: readOnly directory is writeable. Skipping testDumpDirNotWritable test."); + return; + } - TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), - "-cp", ".", - "-Djdk.internal.lambda.dumpProxyClasses=readOnly", - "-Djava.security.manager", - "com.example.TestLambda"); - assertEquals(tr.testOutput.stream() - .filter(s -> s.startsWith("WARNING")) - .peek(s -> assertTrue(s.contains("not writable"))) - .count(), - 1, "only show error once"); - tr.assertZero("Should still return 0"); - - TestUtil.removeAll(Paths.get("readOnly")); + TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), + "-cp", ".", + "-Djdk.internal.lambda.dumpProxyClasses=readOnly", + "-Djava.security.manager", + "com.example.TestLambda"); + assertEquals(tr.testOutput.stream() + .filter(s -> s.startsWith("WARNING")) + .peek(s -> assertTrue(s.contains("not writable"))) + .count(), + 1, "only show error once"); + tr.assertZero("Should still return 0"); + } finally { + TestUtil.removeAll(Paths.get("readOnly")); + } } @Test diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/java/util/Properties/LoadAndStoreXML.java --- a/jdk/test/java/util/Properties/LoadAndStoreXML.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/java/util/Properties/LoadAndStoreXML.java Wed Jul 05 19:43:07 2017 +0200 @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -47,6 +48,7 @@ import java.util.PropertyPermission; public class LoadAndStoreXML { + static final String bomChar = "\uFEFF"; /** * Simple policy implementation that grants a set of permissions to @@ -125,13 +127,14 @@ * Sanity test that properties saved with Properties#storeToXML can be * read with Properties#loadFromXML. */ - static void testLoadAndStore(String encoding) throws IOException { + static void testLoadAndStore(String encoding, boolean appendBOM) throws IOException { System.out.println("testLoadAndStore, encoding=" + encoding); Properties props = new Properties(); + props.put("k0", "\u6C34"); props.put("k1", "foo"); props.put("k2", "bar"); - props.put("k3", "\\u0020\\u0391\\u0392\\u0393\\u0394\\u0395\\u0396\\u0397"); + props.put("k3", "\u0020\u0391\u0392\u0393\u0394\u0395\u0396\u0397"); props.put("k4", "\u7532\u9aa8\u6587"); props.put("k5", "/lib/jaxp.properties"); @@ -141,7 +144,17 @@ throw new RuntimeException("OutputStream closed by storeToXML"); Properties p = new Properties(); - TestInputStream in = new TestInputStream(out.toByteArray()); + TestInputStream in; + if (appendBOM) { + byte[] byteOrderMark = bomChar.getBytes(Charset.forName(encoding)); + byte[] outArray = out.toByteArray(); + byte[] inputArray = new byte[byteOrderMark.length + outArray.length]; + System.arraycopy(byteOrderMark, 0, inputArray, 0, byteOrderMark.length); + System.arraycopy(outArray, 0, inputArray, byteOrderMark.length, outArray.length); + in = new TestInputStream(inputArray); + } else { + in = new TestInputStream(out.toByteArray()); + } p.loadFromXML(in); if (in.isOpen()) throw new RuntimeException("InputStream not closed by loadFromXML"); @@ -231,8 +244,12 @@ public static void main(String[] args) throws IOException { - testLoadAndStore("UTF-8"); - testLoadAndStore("UTF-16"); + testLoadAndStore("UTF-8", false); + testLoadAndStore("UTF-16", false); + testLoadAndStore("UTF-16BE", false); + testLoadAndStore("UTF-16LE", false); + testLoadAndStore("UTF-16BE", true); + testLoadAndStore("UTF-16LE", true); testLoadWithoutEncoding(); testLoadWithBadEncoding(); testStoreWithBadEncoding(); @@ -250,7 +267,7 @@ Policy.setPolicy(p); System.setSecurityManager(new SecurityManager()); try { - testLoadAndStore("UTF-8"); + testLoadAndStore("UTF-8", false); } finally { // turn off security manager and restore policy System.setSecurityManager(null); diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/nio/ch/ServerSocketAdaptorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/nio/ch/ServerSocketAdaptorTest.java Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024832 + */ + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.SocketException; +import java.nio.channels.ServerSocketChannel; + +public class ServerSocketAdaptorTest { + + public static void main(String[] args) throws IOException { + + String message = null; + + try (ServerSocket s = new ServerSocket()) { + s.accept(); + throw new AssertionError(); + } catch (IOException e) { + message = e.getMessage(); + } + + try (ServerSocket ss = ServerSocketChannel.open().socket()) { + + assert !ss.isBound() : "the assumption !ss.isBound() doesn't hold"; + + try { + ss.accept(); + throw new AssertionError(); + } catch (Exception e) { + if (e instanceof SocketException && message.equals(e.getMessage())) { + return; + } else { + throw new AssertionError( + "Expected to throw SocketException with a particular message", e); + } + } + } + } +} diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/security/krb5/auto/KDC.java --- a/jdk/test/sun/security/krb5/auto/KDC.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/sun/security/krb5/auto/KDC.java Wed Jul 05 19:43:07 2017 +0200 @@ -141,6 +141,8 @@ private BlockingQueue q = new ArrayBlockingQueue<>(100); // Options private Map options = new HashMap<>(); + // Realm-specific krb5.conf settings + private List conf = new ArrayList<>(); private Thread thread1, thread2, thread3; DatagramSocket u1 = null; @@ -243,7 +245,7 @@ /** * Sets an option * @param key the option name - * @param obj the value + * @param value the value */ public void setOption(Option key, Object value) { if (value == null) { @@ -373,6 +375,13 @@ } /** + * Add realm-specific krb5.conf setting + */ + public void addConf(String s) { + conf.add(s); + } + + /** * Writes a krb5.conf for one or more KDC that includes KDC locations for * each realm and the default realm name. You can also add extra strings * into the file. The method should be called like: @@ -397,6 +406,7 @@ * [realms] * REALM.NAME = { * kdc = host:port_number + * # realm-specific settings * } * * @@ -444,10 +454,10 @@ } } sb.append("\n[realms]\n"); - sb.append(realmLineForKDC(kdc)); + sb.append(kdc.realmLine()); for (Object o: more) { if (o instanceof KDC) { - sb.append(realmLineForKDC((KDC)o)); + sb.append(((KDC)o).realmLine()); } } FileOutputStream fos = new FileOutputStream(f); @@ -1133,14 +1143,16 @@ /** * Generates a line for a KDC to put inside [realms] of krb5.conf - * @param kdc the KDC - * @return REALM.NAME = { kdc = host:port } + * @return REALM.NAME = { kdc = host:port etc } */ - private static String realmLineForKDC(KDC kdc) { - return String.format("%s = {\n kdc = %s:%d\n}\n", - kdc.realm, - kdc.kdc, - kdc.port); + private String realmLine() { + StringBuilder sb = new StringBuilder(); + sb.append(realm).append(" = {\n kdc = ") + .append(kdc).append(':').append(port).append('\n'); + for (String s: conf) { + sb.append(" ").append(s).append('\n'); + } + return sb.append("}\n").toString(); } /** diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/security/krb5/auto/UdpTcp.java --- a/jdk/test/sun/security/krb5/auto/UdpTcp.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/sun/security/krb5/auto/UdpTcp.java Wed Jul 05 19:43:07 2017 +0200 @@ -43,9 +43,15 @@ OneKDC kdc = new OneKDC(null); kdc.writeJAASConf(); - KDC.saveConfig(OneKDC.KRB5_CONF, kdc, - "udp_preference_limit = " - + (args[0].equals("UDP") ? "1000" : "100")); + // Two styles of kdc_timeout setting. One global, one realm-specific. + if (args[0].equals("UDP")) { + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "kdc_timeout = 10s"); + } else { + kdc.addConf("kdc_timeout = 10s"); + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "udp_preference_limit = 1"); + } Config.refresh(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); @@ -56,7 +62,7 @@ for (String line: new String(bo.toByteArray()).split("\n")) { if (line.contains(">>> KDCCommunication")) { - if (!line.contains(args[0])) { + if (!line.contains(args[0]) || !line.contains("timeout=10000")) { throw new Exception("No " + args[0] + " in: " + line); } } diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/security/pkcs11/PKCS11Test.java --- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 19:43:07 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -457,7 +457,7 @@ osMap.put("SunOS-x86-32", new String[]{"/usr/lib/mps/"}); osMap.put("SunOS-amd64-64", new String[]{"/usr/lib/mps/64/"}); osMap.put("Linux-i386-32", new String[]{ - "/usr/lib/i386-linux-gnu/", "/usr/lib/"}); + "/usr/lib/i386-linux-gnu/", "/usr/lib32/", "/usr/lib/"}); osMap.put("Linux-amd64-64", new String[]{ "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", "/usr/lib64/"}); diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/security/tools/jarsigner/certpolicy.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/tools/jarsigner/certpolicy.sh Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,80 @@ +# +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8036709 +# @summary Java 7 jarsigner displays warning about cert policy tree +# +# @run shell certpolicy.sh +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +KT="$TESTJAVA/bin/keytool $TESTTOOLVMOPTS \ + -keypass changeit -storepass changeit -keystore ks -keyalg rsa" +JS="$TESTJAVA/bin/jarsigner $TESTTOOLVMOPTS -storepass changeit -keystore ks" +JAR="$TESTJAVA/bin/jar $TESTTOOLVMOPTS" + +rm ks 2> /dev/null +$KT -genkeypair -alias ca -dname CN=CA -ext bc +$KT -genkeypair -alias int -dname CN=Int +$KT -genkeypair -alias ee -dname CN=EE + +# CertificatePolicies [[PolicyId: [1.2.3]], [PolicyId: [1.2.4]]] +# PolicyConstraints: [Require: 0; Inhibit: unspecified] +$KT -certreq -alias int | \ + $KT -gencert -rfc -alias ca \ + -ext 2.5.29.32="30 0C 30 04 06 02 2A 03 30 04 06 02 2A 04" \ + -ext "2.5.29.36=30 03 80 01 00" -ext bc | \ + $KT -import -alias int + +# CertificatePolicies [[PolicyId: [1.2.3]]] +$KT -certreq -alias ee | \ + $KT -gencert -rfc -alias int \ + -ext 2.5.29.32="30 06 30 04 06 02 2A 03" | \ + $KT -import -alias ee + +$KT -export -alias ee -rfc > cc +$KT -export -alias int -rfc >> cc +$KT -export -alias ca -rfc >> cc + +$KT -delete -alias int + +ERR='' +$JAR cvf a.jar cc + +# Make sure the certchain in the signed jar contains all 3 certs +$JS -strict -certchain cc a.jar ee -debug || ERR="sign" +$JS -strict -verify a.jar -debug || ERR="$ERR verify" + +if [ "$ERR" = "" ]; then + echo "Success" + exit 0 +else + echo "Failed: $ERR" + exit 1 +fi + diff -r ba3dc5355ed1 -r 4a09f5d30be8 jdk/test/sun/security/tools/keytool/autotest.sh --- a/jdk/test/sun/security/tools/keytool/autotest.sh Wed Jul 05 19:42:33 2017 +0200 +++ b/jdk/test/sun/security/tools/keytool/autotest.sh Wed Jul 05 19:43:07 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -72,6 +72,8 @@ Linux ) if [ $B32 = true ]; then LIBNAME=`find_one \ + "/usr/lib32/libsoftokn3.so" \ + "/usr/lib32/nss/libsoftokn3.so" \ "/usr/lib/libsoftokn3.so" \ "/usr/lib/i386-linux-gnu/nss/libsoftokn3.so" \ "/usr/lib/nss/libsoftokn3.so"` diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/.hgtags --- a/langtools/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -257,3 +257,4 @@ 72efbe612e494f98b9c3ede1b4a3d02304e1e9cc jdk9-b12 2c8bb81b5d48161019218c7604fa88c67edc6105 jdk9-b13 1df3f53b9d980b66739f05e14053381ffb0f38ee jdk9-b14 +8666a9611eb8ba711b001bf8d942282e3e2d8e3d jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 05 19:43:07 2017 +0200 @@ -4696,7 +4696,7 @@ assembleClassSig(rawOuter ? types.erasure(outer) : outer); - append('.'); + append(rawOuter ? '$' : '.'); Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); append(rawOuter ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength()) diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jul 05 19:43:07 2017 +0200 @@ -1221,25 +1221,102 @@ } //slow path + Symbol sym = quicklyResolveMethod(env, tree); + + if (sym == null) { + result = ArgumentExpressionKind.POLY; + return; + } + + result = analyzeCandidateMethods(sym, ArgumentExpressionKind.PRIMITIVE, + argumentKindAnalyzer); + } + //where + private boolean isSimpleReceiver(JCTree rec) { + switch (rec.getTag()) { + case IDENT: + return true; + case SELECT: + return isSimpleReceiver(((JCFieldAccess)rec).selected); + case TYPEAPPLY: + case TYPEARRAY: + return true; + case ANNOTATED_TYPE: + return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); + case APPLY: + return true; + default: + return false; + } + } + private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { + return argumentKindAnalyzer.reduce(result, kind); + } + MethodAnalyzer argumentKindAnalyzer = + new MethodAnalyzer() { + @Override + public ArgumentExpressionKind process(MethodSymbol ms) { + return ArgumentExpressionKind.methodKind(ms, types); + } + @Override + public ArgumentExpressionKind reduce(ArgumentExpressionKind kind1, + ArgumentExpressionKind kind2) { + switch (kind1) { + case PRIMITIVE: return kind2; + case NO_POLY: return kind2.isPoly() ? kind2 : kind1; + case POLY: return kind1; + default: + Assert.error(); + return null; + } + } + @Override + public boolean shouldStop(ArgumentExpressionKind result) { + return result.isPoly(); + } + }; + + @Override + public void visitLiteral(JCLiteral tree) { + Type litType = attr.litType(tree.typetag); + result = ArgumentExpressionKind.standaloneKind(litType, types); + } + + @Override + void skip(JCTree tree) { + result = ArgumentExpressionKind.NO_POLY; + } + + private Symbol quicklyResolveMethod(Env env, final JCMethodInvocation tree) { final JCExpression rec = tree.meth.hasTag(SELECT) ? ((JCFieldAccess)tree.meth).selected : null; if (rec != null && !isSimpleReceiver(rec)) { - //give up if receiver is too complex (to cut down analysis time) - result = ArgumentExpressionKind.POLY; - return; + return null; } - Type site = rec != null ? - attribSpeculative(rec, env, attr.unknownTypeExprInfo).type : - env.enclClass.sym.type; + Type site; - while (site.hasTag(TYPEVAR)) { - site = site.getUpperBound(); + if (rec != null) { + if (rec.hasTag(APPLY)) { + Symbol recSym = quicklyResolveMethod(env, (JCMethodInvocation) rec); + if (recSym == null) + return null; + Symbol resolvedReturnType = + analyzeCandidateMethods(recSym, syms.errSymbol, returnSymbolAnalyzer); + if (resolvedReturnType == null) + return null; + site = resolvedReturnType.type; + } else { + site = attribSpeculative(rec, env, attr.unknownTypeExprInfo).type; + } + } else { + site = env.enclClass.sym.type; } List args = rs.dummyArgs(tree.args.length()); + Name name = TreeInfo.name(tree.meth); Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.nil(), MethodResolutionPhase.VARARITY) { @Override @@ -1254,61 +1331,60 @@ } }; - Symbol sym = rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + return rs.lookupMethod(env, tree, site.tsym, rs.arityMethodCheck, lh); + } + //where: + MethodAnalyzer returnSymbolAnalyzer = new MethodAnalyzer() { + @Override + public Symbol process(MethodSymbol ms) { + ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types); + return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null; + } + @Override + public Symbol reduce(Symbol s1, Symbol s2) { + return s1 == syms.errSymbol ? s2 : s1 == s2 ? s1 : null; + } + @Override + public boolean shouldStop(Symbol result) { + return result == null; + } + }; - if (sym.kind == Kinds.AMBIGUOUS) { - Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); - result = ArgumentExpressionKind.PRIMITIVE; - for (Symbol s : err.ambiguousSyms) { - if (result.isPoly()) break; - if (s.kind == Kinds.MTH) { - result = reduce(ArgumentExpressionKind.methodKind(s, types)); + /** + * Process the result of Resolve.lookupMethod. If sym is a method symbol, the result of + * MethodAnalyzer.process is returned. If sym is an ambiguous symbol, all the candidate + * methods are inspected one by one, using MethodAnalyzer.process. The outcomes are + * reduced using MethodAnalyzer.reduce (using defaultValue as the first value over which + * the reduction runs). MethodAnalyzer.shouldStop can be used to stop the inspection early. + */ + E analyzeCandidateMethods(Symbol sym, E defaultValue, MethodAnalyzer analyzer) { + switch (sym.kind) { + case Kinds.MTH: + return analyzer.process((MethodSymbol) sym); + case Kinds.AMBIGUOUS: + Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); + E res = defaultValue; + for (Symbol s : err.ambiguousSyms) { + if (s.kind == Kinds.MTH) { + res = analyzer.reduce(res, analyzer.process((MethodSymbol) s)); + if (analyzer.shouldStop(res)) + return res; + } } - } - } else { - result = (sym.kind == Kinds.MTH) ? - ArgumentExpressionKind.methodKind(sym, types) : - ArgumentExpressionKind.NO_POLY; + return res; + default: + return defaultValue; } } - //where - private boolean isSimpleReceiver(JCTree rec) { - switch (rec.getTag()) { - case IDENT: - return true; - case SELECT: - return isSimpleReceiver(((JCFieldAccess)rec).selected); - case TYPEAPPLY: - case TYPEARRAY: - return true; - case ANNOTATED_TYPE: - return isSimpleReceiver(((JCAnnotatedType)rec).underlyingType); - default: - return false; - } - } - private ArgumentExpressionKind reduce(ArgumentExpressionKind kind) { - switch (result) { - case PRIMITIVE: return kind; - case NO_POLY: return kind.isPoly() ? kind : result; - case POLY: return result; - default: - Assert.error(); - return null; - } - } + } - @Override - public void visitLiteral(JCLiteral tree) { - Type litType = attr.litType(tree.typetag); - result = ArgumentExpressionKind.standaloneKind(litType, types); - } + /** Analyzer for methods - used by analyzeCandidateMethods. */ + interface MethodAnalyzer { + E process(MethodSymbol ms); + E reduce(E e1, E e2); + boolean shouldStop(E result); + } - @Override - void skip(JCTree tree) { - result = ArgumentExpressionKind.NO_POLY; - } - } //where private EnumSet deferredCheckerTags = EnumSet.of(LAMBDA, REFERENCE, PARENS, TYPECAST, diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed Jul 05 19:43:07 2017 +0200 @@ -1925,6 +1925,13 @@ return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); } + void removeLastRange() { + Range lastRange = lastRange(); + if (lastRange != null) { + aliveRanges.remove(lastRange); + } + } + @Override public String toString() { if (aliveRanges == null) { @@ -1955,9 +1962,7 @@ } } } else { - if (!aliveRanges.isEmpty()) { - aliveRanges.remove(aliveRanges.size() - 1); - } + removeLastRange(); } } @@ -1965,16 +1970,14 @@ if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.length == Character.MAX_VALUE; + return lastRange().length == Character.MAX_VALUE; } public boolean isLastRangeInitialized() { if (aliveRanges.isEmpty()) { return false; } - Range range = lastRange(); - return range.start_pc != Character.MAX_VALUE; + return lastRange().start_pc != Character.MAX_VALUE; } public Range getWidestRange() { @@ -2095,7 +2098,7 @@ v.closeRange(length); putVar(v); } else { - v.lastRange().start_pc = Character.MAX_VALUE; + v.removeLastRange(); } } } diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jul 05 19:43:07 2017 +0200 @@ -1800,8 +1800,7 @@ genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); thenExit = code.branch(goto_); if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { - code.closeAliveRanges(tree.thenpart, - thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp); + code.closeAliveRanges(tree.thenpart, code.cp); } } if (elseChain != null) { diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/test/tools/javac/flow/LVTHarness.java --- a/langtools/test/tools/javac/flow/LVTHarness.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/test/tools/javac/flow/LVTHarness.java Wed Jul 05 19:43:07 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /* * @test - * @bug 7047734 8027660 - * @summary The LVT is not generated correctly during some try/catch scenarios; + * @bug 7047734 8027660 8037937 + * @summary The LVT is not generated correctly during some try/catch scenarios * javac crash while creating LVT entry for a local variable defined in * an inner block * @library /tools/javac/lib @@ -120,7 +120,7 @@ for (Map.Entry entry : aliveRangeMap.entrySet()) { if (!seenAliveRanges.contains(entry.getKey())) { error("Redundant @AliveRanges annotation on method " + - entry.getKey().elem); + entry.getKey().elem + " with key " + entry.getKey()); } } } @@ -134,7 +134,7 @@ for (Method method : classFile.methods) { for (ElementKey elementKey: aliveRangeMap.keySet()) { String methodDesc = method.getName(constantPool) + - method.descriptor.getParameterTypes(constantPool); + method.descriptor.getParameterTypes(constantPool).replace(" ", ""); if (methodDesc.equals(elementKey.elem.toString())) { checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); seenAliveRanges.add(elementKey); diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/test/tools/javac/flow/tests/TestCaseIfElse.java --- a/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Wed Jul 05 19:42:33 2017 +0200 +++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Wed Jul 05 19:43:07 2017 +0200 @@ -33,7 +33,7 @@ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) - void m2(String[] args) { + void m2() { Object o; int i = 5; if (i != 5) { @@ -45,4 +45,19 @@ } o = "finish"; } + + @AliveRange(varName="o", bytecodeStart=11, bytecodeLength=3) + @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=2) + Object m3(boolean cond1, boolean cond2) { + Object o; + if (cond1) { + if (cond2) { + o = "then"; + } else { + o = "else"; + return null; + } + } + return null; + } } diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/test/tools/javac/lambda/T8031967.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8031967.java Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8031967 + * @summary Ensure javac can handle very deeply nested chain of method invocations occurring as + * a parameter to other method invocations. + * @run main T8031967 + */ + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import javax.tools.DiagnosticListener; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +import com.sun.source.util.JavacTask; + +public class T8031967 { + + public static void main(String... args) throws IOException { + new T8031967().run(); + } + + final int depth = 50; + + private void run() throws IOException { + runTestCase(true); + runTestCase(false); + } + + private void runTestCase(boolean withErrors) throws IOException { + StringBuilder code = new StringBuilder(); + + code.append("public class Test {\n" + + " private void test() {\n" + + " GroupLayout l = new GroupLayout();\n" + + " l.setHorizontalGroup(\n"); + + gen(code, depth); + code.append(" );\n" + + " }\n"); + if (!withErrors) { + code.append(" class GroupLayout {\n" + + " ParallelGroup createParallelGroup() {return null;}\n" + + " ParallelGroup createParallelGroup(int i) {return null;}\n" + + " ParallelGroup createParallelGroup(int i, int j) {return null;}\n" + + " void setHorizontalGroup(Group g) { }\n" + + " }\n" + + " \n" + + " class Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(long l) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n" + + " class ParallelGroup extends Group {\n" + + " Group addGroup(Group g) { return this; }\n" + + " Group addGroup(int i, Group g) { return this; }\n" + + " Group addGap(int i) { return this; }\n" + + " Group addGap(int i, int j) { return this; }\n" + + " Group addComponent(Object c) { return this; }\n" + + " Group addComponent(int i, Object c) { return this; }\n" + + " }\n"); + } + + code.append("}\n"); + + JavaSource source = new JavaSource(code.toString()); + List sourceList = Arrays.asList(source); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticListener noErrors = (diagnostic) -> { + throw new IllegalStateException("Should not produce errors: " + diagnostic); + }; + JavacTask task = (JavacTask) compiler.getTask(null, null, withErrors ? null : noErrors, + null, null, sourceList); + + task.analyze(); + } + + private void gen(StringBuilder code, int depth) { + code.append("l.createParallelGroup()\n"); + if (depth > 0) { + code.append(".addGroup(\n"); + gen(code, depth - 1); + code.append(")"); + } + + code.append(".addGap(1)\n" + + ".addComponent(new Object())\n" + + ".addGap(1)\n" + + ".addComponent(new Object())"); + } + + class JavaSource extends SimpleJavaFileObject { + + final String code; + public JavaSource(String code) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } + } +} diff -r ba3dc5355ed1 -r 4a09f5d30be8 langtools/test/tools/javac/types/BadSigTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/types/BadSigTest.java Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8037934 + * @summary Javac generates invalid signatures for local types + * @run main BadSigTest + */ + +public class BadSigTest { + void m(){ + class Local1{} + class Local2 extends Local1{} + Local2.class.getTypeParameters(); + } + public static void main(String[] args) { + new BadSigTest().m(); + } +} diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/.hgtags --- a/nashorn/.hgtags Wed Jul 05 19:42:33 2017 +0200 +++ b/nashorn/.hgtags Wed Jul 05 19:43:07 2017 +0200 @@ -248,3 +248,4 @@ 282e9a675e079cc84dbfaa4c10050f08397faab0 jdk9-b12 be4580ae56e2ef0ce521d3f840753eaa83cacf33 jdk9-b13 806df06b6ac58d3e9c9c6a680dbdd7a6c94ca700 jdk9-b14 +32b66f4661eac52f8b04fb3d7703feb2c96febb7 jdk9-b15 diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/make/build.xml --- a/nashorn/make/build.xml Wed Jul 05 19:42:33 2017 +0200 +++ b/nashorn/make/build.xml Wed Jul 05 19:43:07 2017 +0200 @@ -196,14 +196,16 @@ - - + + - + @@ -211,6 +213,19 @@ + + + + + + + + + + + + diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/samples/filebrowser.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/samples/filebrowser.js Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,100 @@ +#// Usage: jjs -fx filebrowser.js -- + +/* + * Copyright (c) 2014, 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 + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Uses -fx and javafx TreeView to visualize directories +if (!$OPTIONS._fx) { + print("Usage: jjs -fx filebrowser.js -- "); + exit(1); +} + +// Java classes used +var File = Java.type("java.io.File"); +var Files = Java.type("java.nio.file.Files"); + +// check directory argument, if passed +var dir = arguments.length > 0? new File(arguments[0]) : new File("."); +if (! dir.isDirectory()) { + print(dir + " is not a directory!"); + exit(2); +} + +// JavaFX classes used +var FXCollections = Java.type("javafx.collections.FXCollections"); +var Scene = Java.type("javafx.scene.Scene"); +var TreeItem = Java.type("javafx.scene.control.TreeItem"); +var TreeView = Java.type("javafx.scene.control.TreeView"); + +// create a subclass of JavaFX TreeItem class +var LazyTreeItem = Java.extend(TreeItem); + +// lazily filling children of a directory LazyTreeItem +function buildChildren(dir) { + var children = FXCollections.observableArrayList(); + var stream = Files.list(dir.toPath()); + stream.forEach(function(path) { + var file = path.toFile(); + var item = file.isDirectory()? + makeLazyTreeItem(file) : new TreeItem(file.name); + children.add(item); + }); + stream.close(); + return children; +} + +// create an instance LazyTreeItem with override methods +function makeLazyTreeItem(dir) { + var item = new LazyTreeItem(dir.name) { + expanded: false, + isLeaf: function() false, + getChildren: function() { + if (! this.expanded) { + // call super class (TreeItem) method + Java.super(item).getChildren().setAll(buildChildren(dir)); + this.expanded = true; + } + // call super class (TreeItem) method + return Java.super(item).getChildren(); + } + } + return item; +} + +// JavaFX start method +function start(stage) { + stage.title = dir.absolutePath; + var rootItem = makeLazyTreeItem(dir); + rootItem.expanded = true; + var tree = new TreeView(rootItem); + stage.scene = new Scene(tree, 300, 450); + stage.show(); +} diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/samples/word_histogram.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/samples/word_histogram.js Wed Jul 05 19:43:07 2017 +0200 @@ -0,0 +1,53 @@ +#nashorn word histogram of a file + +/* + * Copyright (c) 2014, 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 + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This example demonstrates how to print word histogram + * of a given text file using regex, array and JSON + * functions. + */ + +if (arguments.length < 1) { + print("Usage: jjs -scripting word_histogram.js -- "); + exit(1); +} + +var obj = {}; + +readFully(arguments[0]). + split(/[^\w+]/). + forEach(function(x) + (x in obj? obj[x]++ : obj[x] = 1)); + +print(JSON.stringify(obj)); + diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 19:42:33 2017 +0200 +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 19:43:07 2017 +0200 @@ -621,6 +621,7 @@ /** * Utilitity to convert this script object to the given type. * + * @param destination type to convert to * @param type destination type to convert to * @return converted object */ diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/src/jdk/nashorn/api/scripting/package-info.java --- a/nashorn/src/jdk/nashorn/api/scripting/package-info.java Wed Jul 05 19:42:33 2017 +0200 +++ b/nashorn/src/jdk/nashorn/api/scripting/package-info.java Wed Jul 05 19:43:07 2017 +0200 @@ -32,7 +32,8 @@ * ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn"); * *

Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable} - * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. See + * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. In addition, + * this package provides nashorn specific extension classes, interfaces and methods. See * {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details. */ package jdk.nashorn.api.scripting; diff -r ba3dc5355ed1 -r 4a09f5d30be8 nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java --- a/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java Wed Jul 05 19:42:33 2017 +0200 +++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java Wed Jul 05 19:43:07 2017 +0200 @@ -32,9 +32,7 @@ * Reference node in AST, i.e. anything not a copy. Important for * AST traversal and cloning. Cloning currently as a rule uses * existingOrSame for references and otherwise existingOrCopy - *

*/ - @Retention(value=RetentionPolicy.RUNTIME) public @interface Reference { // EMPTY