--- a/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
cf139f925da04c8bd7efd33270a0315d72b338d3 jdk-9+149
17469f16fbb406ec9f0dd262ce776ab6efbc38f1 jdk-9+150
37b95df0042ae0687324e1f7dc4a2519e230e704 jdk-9+151
+ab2c8b03c3284fcbdd157551a66f807e3a182d9b jdk-9+152
+d7034ff7f8e257e81c9f95c7785dd4eaaa3c2afc jdk-9+153
--- a/.hgtags-top-repo Thu Jan 19 10:55:07 2017 -0500
+++ b/.hgtags-top-repo Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
b119012d1c2ab2570fe8718633840d0c1f1f441d jdk-9+149
6234069ff9789f7582e1faa32cb6283cbd1a5a2d jdk-9+150
71a766d4c18041a7f833ee22823125b02e1a7f1e jdk-9+151
+ef056360ddf3977d7d2ddbeb456a4d612d19ea05 jdk-9+152
+816a6d03a7c44edfbd8780110529f1bdc3964fb9 jdk-9+153
--- a/common/autoconf/basics.m4 Thu Jan 19 10:55:07 2017 -0500
+++ b/common/autoconf/basics.m4 Tue Jan 24 00:30:23 2017 +0100
@@ -1040,12 +1040,36 @@
AC_SUBST(TAR_SUPPORTS_TRANSFORM)
])
+AC_DEFUN([BASIC_CHECK_GREP],
+[
+ # Test that grep supports -Fx with a list of pattern which includes null pattern.
+ # This is a problem for the grep resident on AIX.
+ AC_MSG_CHECKING([that grep ($GREP) -Fx handles empty lines in the pattern list correctly])
+ # Multiple subsequent spaces..
+ STACK_SPACES='aaa bbb ccc'
+ # ..converted to subsequent newlines, causes STACK_LIST to be a list with some empty
+ # patterns in it.
+ STACK_LIST=${STACK_SPACES// /$'\n'}
+ NEEDLE_SPACES='ccc bbb aaa'
+ NEEDLE_LIST=${NEEDLE_SPACES// /$'\n'}
+ RESULT="$($GREP -Fvx "$STACK_LIST" <<< "$NEEDLE_LIST")"
+ if test "x$RESULT" == "x"; then
+ AC_MSG_RESULT([yes])
+ else
+ if test "x$OPENJDK_TARGET_OS" = "xaix"; then
+ ADDINFO="Please make sure you use GNU grep, usually found at /opt/freeware/bin."
+ fi
+ AC_MSG_ERROR([grep does not handle -Fx correctly. ${ADDINFO}])
+ fi
+])
+
AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
[
BASIC_CHECK_GNU_MAKE
BASIC_CHECK_FIND_DELETE
BASIC_CHECK_TAR
+ BASIC_CHECK_GREP
# These tools might not be installed by default,
# need hint on how to install them.
--- a/common/autoconf/flags.m4 Thu Jan 19 10:55:07 2017 -0500
+++ b/common/autoconf/flags.m4 Tue Jan 24 00:30:23 2017 +0100
@@ -815,11 +815,6 @@
$2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
fi
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
- $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
- fi
-
$2CFLAGS_JDK="${$2CFLAGS_JDK} ${$2EXTRA_CFLAGS}"
$2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2EXTRA_CXXFLAGS}"
$2LDFLAGS_JDK="${$2LDFLAGS_JDK} ${$2EXTRA_LDFLAGS}"
--- a/common/autoconf/generated-configure.sh Thu Jan 19 10:55:07 2017 -0500
+++ b/common/autoconf/generated-configure.sh Tue Jan 24 00:30:23 2017 +0100
@@ -3731,6 +3731,8 @@
+
+
# Check if build directory is on local disk. If not possible to determine,
# we prefer to claim it's local.
# Argument 1: directory to test
@@ -5178,7 +5180,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1484328385
+DATE_WHEN_GENERATED=1485214214
###############################################################################
#
@@ -21251,6 +21253,29 @@
+ # Test that grep supports -Fx with a list of pattern which includes null pattern.
+ # This is a problem for the grep resident on AIX.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking that grep ($GREP) -Fx handles empty lines in the pattern list correctly" >&5
+$as_echo_n "checking that grep ($GREP) -Fx handles empty lines in the pattern list correctly... " >&6; }
+ # Multiple subsequent spaces..
+ STACK_SPACES='aaa bbb ccc'
+ # ..converted to subsequent newlines, causes STACK_LIST to be a list with some empty
+ # patterns in it.
+ STACK_LIST=${STACK_SPACES// /$'\n'}
+ NEEDLE_SPACES='ccc bbb aaa'
+ NEEDLE_LIST=${NEEDLE_SPACES// /$'\n'}
+ RESULT="$($GREP -Fvx "$STACK_LIST" <<< "$NEEDLE_LIST")"
+ if test "x$RESULT" == "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ if test "x$OPENJDK_TARGET_OS" = "xaix"; then
+ ADDINFO="Please make sure you use GNU grep, usually found at /opt/freeware/bin."
+ fi
+ as_fn_error $? "grep does not handle -Fx correctly. ${ADDINFO}" "$LINENO" 5
+ fi
+
+
# These tools might not be installed by default,
# need hint on how to install them.
@@ -49920,11 +49945,6 @@
CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
fi
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
- CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
- fi
-
CFLAGS_JDK="${CFLAGS_JDK} ${EXTRA_CFLAGS}"
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${EXTRA_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK} ${EXTRA_LDFLAGS}"
@@ -50743,11 +50763,6 @@
OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
fi
- if test "x$OPENJDK_TARGET_OS" = xsolaris; then
- OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
- OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
- fi
-
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CFLAGS}"
OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CXXFLAGS}"
OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_LDFLAGS}"
--- a/common/autoconf/spec.gmk.in Thu Jan 19 10:55:07 2017 -0500
+++ b/common/autoconf/spec.gmk.in Tue Jan 24 00:30:23 2017 +0100
@@ -274,8 +274,6 @@
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
-BUILD_HOTSPOT=@BUILD_HOTSPOT@
-
BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@
ENABLE_GENERATE_CLASSLIST := @ENABLE_GENERATE_CLASSLIST@
@@ -642,7 +640,6 @@
NICE:=@NICE@
PATCH:=@PATCH@
PRINTF:=@PRINTF@
-PWD:=@THEPWDCMD@
RM:=@RM@
RMDIR:=@RMDIR@
SED:=@SED@
--- a/common/conf/jib-profiles.js Thu Jan 19 10:55:07 2017 -0500
+++ b/common/conf/jib-profiles.js Tue Jan 24 00:30:23 2017 +0100
@@ -870,7 +870,7 @@
jtreg: {
server: "javare",
revision: "4.2",
- build_number: "b04",
+ build_number: "b05",
checksum_file: "MD5_VALUES",
file: "jtreg_bin-4.2.zip",
environment_name: "JT_HOME",
--- a/corba/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/corba/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
00b19338e505690abe93d5995ed74a473d969c2c jdk-9+149
9205e980062a5c4530b51021c6e274025f4ccbdf jdk-9+150
77f827f5bbad3ef795664bc675f72d98d156b9f8 jdk-9+151
+ff8cb43c07c069b1debdee44cb88ca22db1ec757 jdk-9+152
+68a8e8658511093b322a46ed04b2a321e1da2a43 jdk-9+153
--- a/hotspot/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/hotspot/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -554,3 +554,5 @@
30e1996bd55da36183434f24ed964adebf9ca71e jdk-9+149
98fe046473c90204cbc9b34c512b9fc10dfb8479 jdk-9+150
2a2ac7d9f52c8cb2b80077e515b5840b947e640c jdk-9+151
+31f1d26c60df7b2e516a4f84160d76ba017d4e09 jdk-9+152
+217ba81b9a4ce8698200370175aa2db86a39f66c jdk-9+153
--- a/jaxp/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
5978df8bfa3894f2b3d07b7256f25f78dffb1f9c jdk-9+149
f85154af719f99a3b4d81b67a8b4c18a650d10f9 jdk-9+150
13c6906bfc861d99dc35a19c80b7a99f0b0ac58d jdk-9+151
+7e3da313b1746578da648155e37dd8526e83153d jdk-9+152
+1384504d2cd0e55c5e0becaeaf40ab05cae959d6 jdk-9+153
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2SAX.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2SAX.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,20 +17,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: DOM2SAX.java,v 1.2.4.1 2005/09/06 11:52:46 pvedula Exp $
- */
-
package com.sun.org.apache.xalan.internal.xsltc.trax;
import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
-import java.util.Vector;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
@@ -58,7 +54,7 @@
private ContentHandler _sax = null;
private LexicalHandler _lex = null;
private SAXImpl _saxImpl = null;
- private Map<String, Stack> _nsPrefixes = new HashMap<>();
+ private Map<String, Stack<String>> _nsPrefixes = new HashMap<>();
public DOM2SAX(Node root) {
_dom = root;
@@ -73,7 +69,7 @@
{
_sax = handler;
if (handler instanceof LexicalHandler) {
- _lex = (LexicalHandler) handler;
+ _lex = (LexicalHandler)handler;
}
if (handler instanceof SAXImpl) {
@@ -90,25 +86,22 @@
throws SAXException
{
boolean pushed = true;
- Stack uriStack = _nsPrefixes.get(prefix);
+ Stack<String> uriStack = _nsPrefixes.get(prefix);
if (uriStack != null) {
if (uriStack.isEmpty()) {
_sax.startPrefixMapping(prefix, uri);
uriStack.push(uri);
- }
- else {
- final String lastUri = (String) uriStack.peek();
+ } else {
+ final String lastUri = uriStack.peek();
if (!lastUri.equals(uri)) {
_sax.startPrefixMapping(prefix, uri);
uriStack.push(uri);
- }
- else {
+ } else {
pushed = false;
}
}
- }
- else {
+ } else {
_sax.startPrefixMapping(prefix, uri);
_nsPrefixes.put(prefix, uriStack = new Stack());
uriStack.push(uri);
@@ -123,7 +116,7 @@
private void endPrefixMapping(String prefix)
throws SAXException
{
- final Stack uriStack = _nsPrefixes.get(prefix);
+ final Stack<String> uriStack = _nsPrefixes.get(prefix);
if (uriStack != null) {
_sax.endPrefixMapping(prefix);
@@ -131,22 +124,6 @@
}
}
- /**
- * If the DOM was created using a DOM 1.0 API, the local name may be
- * null. If so, get the local name from the qualified name before
- * generating the SAX event.
- */
- private static String getLocalName(Node node) {
- final String localName = node.getLocalName();
-
- if (localName == null) {
- final String qname = node.getNodeName();
- final int col = qname.lastIndexOf(':');
- return (col > 0) ? qname.substring(col + 1) : qname;
- }
- return localName;
- }
-
public void parse(InputSource unused) throws IOException, SAXException {
parse(_dom);
}
@@ -173,8 +150,8 @@
* declarations.
*/
private void parse(Node node) throws IOException, SAXException {
- Node first = null;
- if (node == null) return;
+ if (node == null)
+ return;
switch (node.getNodeType()) {
case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE
@@ -198,7 +175,6 @@
_sax.characters(cdata.toCharArray(), 0, cdata.length());
}
break;
-
case Node.COMMENT_NODE: // should be handled!!!
if (_lex != null) {
final String value = node.getNodeValue();
@@ -216,10 +192,9 @@
}
_sax.endDocument();
break;
-
case Node.ELEMENT_NODE:
String prefix;
- Vector pushedPrefixes = new Vector();
+ ArrayList<String> pushedPrefixes = new ArrayList<>();
final AttributesImpl attrs = new AttributesImpl();
final NamedNodeMap map = node.getAttributes();
final int length = map.getLength();
@@ -235,7 +210,7 @@
final int colon = qnameAttr.lastIndexOf(':');
prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
if (startPrefixMapping(prefix, uriAttr)) {
- pushedPrefixes.addElement(prefix);
+ pushedPrefixes.add(prefix);
}
}
}
@@ -248,27 +223,25 @@
// Ignore NS declarations here
if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
final String uriAttr = attr.getNamespaceURI();
- final String localNameAttr = getLocalName(attr);
// Uri may be implicitly declared
if (uriAttr != null) {
final int colon = qnameAttr.lastIndexOf(':');
if (colon > 0) {
prefix = qnameAttr.substring(0, colon);
- }
- else {
+ } else {
// If no prefix for this attr, we need to create
// one because we cannot use the default ns
prefix = BasisLibrary.generatePrefix();
qnameAttr = prefix + ':' + qnameAttr;
}
if (startPrefixMapping(prefix, uriAttr)) {
- pushedPrefixes.addElement(prefix);
+ pushedPrefixes.add(prefix);
}
}
// Add attribute to list
- attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr),
+ attrs.addAttribute(attr.getNamespaceURI(), attr.getLocalName(),
qnameAttr, "CDATA", attr.getNodeValue());
}
}
@@ -276,22 +249,21 @@
// Now process the element itself
final String qname = node.getNodeName();
final String uri = node.getNamespaceURI();
- final String localName = getLocalName(node);
+ final String localName = node.getLocalName();
- // Uri may be implicitly declared
+ // URI may be implicitly declared
if (uri != null) {
final int colon = qname.lastIndexOf(':');
prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
if (startPrefixMapping(prefix, uri)) {
- pushedPrefixes.addElement(prefix);
+ pushedPrefixes.add(prefix);
}
}
// Generate SAX event to start element
if (_saxImpl != null) {
_saxImpl.startElement(uri, localName, qname, attrs, node);
- }
- else {
+ } else {
_sax.startElement(uri, localName, qname, attrs);
}
@@ -308,15 +280,13 @@
// Generate endPrefixMapping() for all pushed prefixes
final int nPushedPrefixes = pushedPrefixes.size();
for (int i = 0; i < nPushedPrefixes; i++) {
- endPrefixMapping((String) pushedPrefixes.elementAt(i));
+ endPrefixMapping(pushedPrefixes.get(i));
}
break;
-
case Node.PROCESSING_INSTRUCTION_NODE:
_sax.processingInstruction(node.getNodeName(),
node.getNodeValue());
break;
-
case Node.TEXT_NODE:
final String data = node.getNodeValue();
_sax.characters(data.toCharArray(), 0, data.length());
@@ -449,36 +419,4 @@
public String getSystemId() {
return null;
}
-
- // Debugging
- private String getNodeTypeFromCode(short code) {
- String retval = null;
- switch (code) {
- case Node.ATTRIBUTE_NODE :
- retval = "ATTRIBUTE_NODE"; break;
- case Node.CDATA_SECTION_NODE :
- retval = "CDATA_SECTION_NODE"; break;
- case Node.COMMENT_NODE :
- retval = "COMMENT_NODE"; break;
- case Node.DOCUMENT_FRAGMENT_NODE :
- retval = "DOCUMENT_FRAGMENT_NODE"; break;
- case Node.DOCUMENT_NODE :
- retval = "DOCUMENT_NODE"; break;
- case Node.DOCUMENT_TYPE_NODE :
- retval = "DOCUMENT_TYPE_NODE"; break;
- case Node.ELEMENT_NODE :
- retval = "ELEMENT_NODE"; break;
- case Node.ENTITY_NODE :
- retval = "ENTITY_NODE"; break;
- case Node.ENTITY_REFERENCE_NODE :
- retval = "ENTITY_REFERENCE_NODE"; break;
- case Node.NOTATION_NODE :
- retval = "NOTATION_NODE"; break;
- case Node.PROCESSING_INSTRUCTION_NODE :
- retval = "PROCESSING_INSTRUCTION_NODE"; break;
- case Node.TEXT_NODE:
- retval = "TEXT_NODE"; break;
- }
- return retval;
- }
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,14 +17,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: SAX2DTM.java,v 1.2.4.1 2005/09/15 08:15:11 suresh_emailid Exp $
- */
+
package com.sun.org.apache.xml.internal.dtm.ref.sax2dtm;
-
-import com.sun.org.apache.xml.internal.dtm.*;
-import com.sun.org.apache.xml.internal.dtm.ref.*;
+import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xml.internal.dtm.DTMManager;
+import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
+import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseIterators;
+import com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault;
+import com.sun.org.apache.xml.internal.dtm.ref.DTMStringPool;
+import com.sun.org.apache.xml.internal.dtm.ref.DTMTreeWalker;
+import com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource;
+import com.sun.org.apache.xml.internal.dtm.ref.NodeLocator;
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
import com.sun.org.apache.xml.internal.res.XMLMessages;
import com.sun.org.apache.xml.internal.utils.FastStringBuffer;
@@ -36,13 +40,23 @@
import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException;
import com.sun.org.apache.xml.internal.utils.XMLString;
import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.xml.transform.Source;
import javax.xml.transform.SourceLocator;
-import org.xml.sax.*;
-import org.xml.sax.ext.*;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ext.DeclHandler;
+import org.xml.sax.ext.LexicalHandler;
/**
* This class implements a DTM that tends to be optimized more for speed than
@@ -82,7 +96,6 @@
*
* Made protected rather than private so SAX2RTFDTM can access it.
*/
- //private FastStringBuffer m_chars = new FastStringBuffer(13, 13);
protected FastStringBuffer m_chars;
/** This vector holds offset and length data.
@@ -102,8 +115,7 @@
/** Namespace support, only relevent at construction time.
* Made protected rather than private so SAX2RTFDTM can access it.
*/
- transient protected java.util.Vector m_prefixMappings =
- new java.util.Vector();
+ transient protected Vector<String> m_prefixMappings = new Vector<>();
/** Namespace support, only relevent at construction time.
* Made protected rather than private so SAX2RTFDTM can access it.
@@ -164,7 +176,7 @@
* Vector of entities. Each record is composed of four Strings:
* publicId, systemID, notationName, and name.
*/
- private Vector m_entities = null;
+ private ArrayList<String> m_entities = null;
/** m_entities public ID offset. */
private static final int ENTITY_FIELD_PUBLICID = 0;
@@ -196,13 +208,15 @@
*/
protected boolean m_useSourceLocationProperty = false;
- /** Made protected for access by SAX2RTFDTM.
+ /** Made protected for access by SAX2RTFDTM.
*/
protected StringVector m_sourceSystemId;
- /** Made protected for access by SAX2RTFDTM.
+
+ /** Made protected for access by SAX2RTFDTM.
*/
protected IntVector m_sourceLine;
- /** Made protected for access by SAX2RTFDTM.
+
+ /** Made protected for access by SAX2RTFDTM.
*/
protected IntVector m_sourceColumn;
@@ -252,23 +266,19 @@
boolean usePrevsib,
boolean newNameTable)
{
-
super(mgr, source, dtmIdentity, whiteSpaceFilter,
xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);
// %OPT% Use smaller sizes for all internal storage units when
// the blocksize is small. This reduces the cost of creating an RTF.
- if (blocksize <= 64)
- {
+ if (blocksize <= 64) {
m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
m_valuesOrPrefixes = new DTMStringPool(16);
m_chars = new FastStringBuffer(7, 10);
m_contextIndexes = new IntStack(4);
m_parents = new IntStack(4);
- }
- else
- {
+ } else {
m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
m_valuesOrPrefixes = new DTMStringPool();
@@ -289,7 +299,7 @@
// m_useSourceLocationProperty=com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl.m_source_location;
m_useSourceLocationProperty = mgr.getSource_location();
m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null;
- m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null;
+ m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null;
m_sourceColumn = (m_useSourceLocationProperty) ? new IntVector() : null;
}
@@ -297,8 +307,7 @@
* Set whether information about document source location
* should be maintained or not.
*/
- public void setUseSourceLocation(boolean useSourceLocation)
- {
+ public void setUseSourceLocation(boolean useSourceLocation) {
m_useSourceLocationProperty = useSourceLocation;
}
@@ -309,17 +318,14 @@
*
* @return The data or qualified name, or DTM.NULL.
*/
- protected int _dataOrQName(int identity)
- {
-
+ protected int _dataOrQName(int identity) {
if (identity < m_size)
return m_dataOrQName.elementAt(identity);
// Check to see if the information requested has been processed, and,
// if not, advance the iterator until we the information has been
// processed.
- while (true)
- {
+ while (true) {
boolean isMore = nextNode();
if (!isMore)
@@ -332,8 +338,7 @@
/**
* Ask the CoRoutine parser to doTerminate and clear the reference.
*/
- public void clearCoRoutine()
- {
+ public void clearCoRoutine() {
clearCoRoutine(true);
}
@@ -344,11 +349,8 @@
* @param callDoTerminate true of doTerminate should be called on the
* coRoutine parser.
*/
- public void clearCoRoutine(boolean callDoTerminate)
- {
-
- if (null != m_incrementalSAXSource)
- {
+ public void clearCoRoutine(boolean callDoTerminate) {
+ if (null != m_incrementalSAXSource) {
if (callDoTerminate)
m_incrementalSAXSource.deliverMoreNodes(false);
@@ -368,9 +370,7 @@
* @param incrementalSAXSource The parser that we want to recieve events from
* on demand.
*/
- public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource)
- {
-
+ public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource) {
// Establish coroutine link so we can request more data
//
// Note: It's possible that some versions of IncrementalSAXSource may
@@ -406,11 +406,9 @@
* Note that IncrementalSAXSource_Filter is package private, hence
* it can be statically referenced using instanceof (CR 6537912).
*/
- public ContentHandler getContentHandler()
- {
-
- if (m_incrementalSAXSource.getClass()
- .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
+ public ContentHandler getContentHandler() {
+ if (m_incrementalSAXSource.getClass().getName()
+ .equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
return (ContentHandler) m_incrementalSAXSource;
else
return this;
@@ -429,11 +427,9 @@
* Note that IncrementalSAXSource_Filter is package private, hence
* it can be statically referenced using instanceof (CR 6537912).
*/
- public LexicalHandler getLexicalHandler()
- {
-
- if (m_incrementalSAXSource.getClass()
- .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
+ public LexicalHandler getLexicalHandler() {
+ if (m_incrementalSAXSource.getClass().getName()
+ .equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
return (LexicalHandler) m_incrementalSAXSource;
else
return this;
@@ -444,8 +440,7 @@
*
* @return null if this model doesn't respond to SAX entity ref events.
*/
- public EntityResolver getEntityResolver()
- {
+ public EntityResolver getEntityResolver() {
return this;
}
@@ -454,8 +449,7 @@
*
* @return null if this model doesn't respond to SAX dtd events.
*/
- public DTDHandler getDTDHandler()
- {
+ public DTDHandler getDTDHandler() {
return this;
}
@@ -464,8 +458,7 @@
*
* @return null if this model doesn't respond to SAX error events.
*/
- public ErrorHandler getErrorHandler()
- {
+ public ErrorHandler getErrorHandler() {
return this;
}
@@ -474,8 +467,7 @@
*
* @return null if this model doesn't respond to SAX Decl events.
*/
- public DeclHandler getDeclHandler()
- {
+ public DeclHandler getDeclHandler() {
return this;
}
@@ -485,8 +477,7 @@
* transformation and the parse run simultaneously. Guidance to the
* DTMManager.
*/
- public boolean needsTwoThreads()
- {
+ public boolean needsTwoThreads() {
return null != m_incrementalSAXSource;
}
@@ -509,9 +500,8 @@
*/
public void dispatchCharactersEvents(int nodeHandle, ContentHandler ch,
boolean normalize)
- throws SAXException
+ throws SAXException
{
-
int identity = makeNodeIdentity(nodeHandle);
if (identity == DTM.NULL)
@@ -519,8 +509,7 @@
int type = _type(identity);
- if (isTextType(type))
- {
+ if (isTextType(type)) {
int dataIndex = m_dataOrQName.elementAt(identity);
int offset = m_data.elementAt(dataIndex);
int length = m_data.elementAt(dataIndex + 1);
@@ -529,13 +518,10 @@
m_chars.sendNormalizedSAXcharacters(ch, offset, length);
else
m_chars.sendSAXcharacters(ch, offset, length);
- }
- else
- {
+ } else {
int firstChild = _firstch(identity);
- if (DTM.NULL != firstChild)
- {
+ if (DTM.NULL != firstChild) {
int offset = -1;
int length = 0;
int startNode = identity;
@@ -545,12 +531,10 @@
do {
type = _type(identity);
- if (isTextType(type))
- {
+ if (isTextType(type)) {
int dataIndex = _dataOrQName(identity);
- if (-1 == offset)
- {
+ if (-1 == offset) {
offset = m_data.elementAt(dataIndex);
}
@@ -560,36 +544,31 @@
identity = getNextNodeIdentity(identity);
} while (DTM.NULL != identity && (_parent(identity) >= startNode));
- if (length > 0)
- {
+ if (length > 0) {
if(normalize)
m_chars.sendNormalizedSAXcharacters(ch, offset, length);
else
m_chars.sendSAXcharacters(ch, offset, length);
}
- }
- else if(type != DTM.ELEMENT_NODE)
- {
+ } else if(type != DTM.ELEMENT_NODE) {
int dataIndex = _dataOrQName(identity);
- if (dataIndex < 0)
- {
+ if (dataIndex < 0) {
dataIndex = -dataIndex;
dataIndex = m_data.elementAt(dataIndex + 1);
}
String str = m_valuesOrPrefixes.indexToString(dataIndex);
- if(normalize)
- FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
- 0, str.length(), ch);
- else
- ch.characters(str.toCharArray(), 0, str.length());
+ if(normalize)
+ FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
+ 0, str.length(), ch);
+ else
+ ch.characters(str.toCharArray(), 0, str.length());
}
}
}
-
/**
* Given a node handle, return its DOM-style node name. This will
* include names such as #text or #document.
@@ -599,39 +578,29 @@
* %REVIEW% Document when empty string is possible...
* %REVIEW-COMMENT% It should never be empty, should it?
*/
- public String getNodeName(int nodeHandle)
- {
-
+ public String getNodeName(int nodeHandle) {
int expandedTypeID = getExpandedTypeID(nodeHandle);
// If just testing nonzero, no need to shift...
int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);
- if (0 == namespaceID)
- {
+ if (0 == namespaceID) {
// Don't retrieve name until/unless needed
// String name = m_expandedNameTable.getLocalName(expandedTypeID);
int type = getNodeType(nodeHandle);
- if (type == DTM.NAMESPACE_NODE)
- {
+ if (type == DTM.NAMESPACE_NODE) {
if (null == m_expandedNameTable.getLocalName(expandedTypeID))
return "xmlns";
else
return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID);
- }
- else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID))
- {
+ } else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID)) {
return m_fixednames[type];
- }
- else
+ } else
return m_expandedNameTable.getLocalName(expandedTypeID);
- }
- else
- {
+ } else {
int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
- if (qnameIndex < 0)
- {
+ if (qnameIndex < 0) {
qnameIndex = -qnameIndex;
qnameIndex = m_data.elementAt(qnameIndex);
}
@@ -648,27 +617,21 @@
* @param nodeHandle the id of the node.
* @return String Name of this node, which may be an empty string.
*/
- public String getNodeNameX(int nodeHandle)
- {
-
+ public String getNodeNameX(int nodeHandle) {
int expandedTypeID = getExpandedTypeID(nodeHandle);
int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);
- if (0 == namespaceID)
- {
+ if (namespaceID == 0) {
String name = m_expandedNameTable.getLocalName(expandedTypeID);
if (name == null)
return "";
else
return name;
- }
- else
- {
+ } else {
int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
- if (qnameIndex < 0)
- {
+ if (qnameIndex < 0) {
qnameIndex = -qnameIndex;
qnameIndex = m_data.elementAt(qnameIndex);
}
@@ -686,11 +649,9 @@
* @return <code>true</code> if the attribute was specified;
* <code>false</code> if it was defaulted.
*/
- public boolean isAttributeSpecified(int attributeHandle)
- {
-
+ public boolean isAttributeSpecified(int attributeHandle) {
// I'm not sure if I want to do anything with this...
- return true; // ??
+ return true; // ??
}
/**
@@ -701,9 +662,7 @@
*
* @return the system identifier String object, or null if there is none.
*/
- public String getDocumentTypeDeclarationSystemIdentifier()
- {
-
+ public String getDocumentTypeDeclarationSystemIdentifier() {
/** @todo: implement this com.sun.org.apache.xml.internal.dtm.DTMDefaultBase abstract method */
error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!");
@@ -717,14 +676,11 @@
* @param identity The node identity (index).
* @return identity+1, or DTM.NULL.
*/
- protected int getNextNodeIdentity(int identity)
- {
-
+ protected int getNextNodeIdentity(int identity) {
identity += 1;
- while (identity >= m_size)
- {
- if (null == m_incrementalSAXSource)
+ while (identity >= m_size) {
+ if (m_incrementalSAXSource == null)
return DTM.NULL;
nextNode();
@@ -739,10 +695,10 @@
* @param nodeHandle The node ID.
* @param ch A non-null reference to a ContentHandler.
*
- * @throws org.xml.sax.SAXException
+ * @throws SAXException
*/
- public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
- throws org.xml.sax.SAXException
+ public void dispatchToEvents(int nodeHandle, ContentHandler ch)
+ throws SAXException
{
DTMTreeWalker treeWalker = m_walker;
@@ -1087,28 +1043,22 @@
* @return String containing the URI of the Unparsed Entity, or an
* empty string if no such entity exists.
*/
- public String getUnparsedEntityURI(String name)
- {
-
+ public String getUnparsedEntityURI(String name) {
String url = "";
- if (null == m_entities)
+ if (null == m_entities) {
return url;
+ }
int n = m_entities.size();
- for (int i = 0; i < n; i += ENTITY_FIELDS_PER)
- {
- String ename = (String) m_entities.elementAt(i + ENTITY_FIELD_NAME);
+ for (int i = 0; i < n; i += ENTITY_FIELDS_PER) {
+ String ename = m_entities.get(i + ENTITY_FIELD_NAME);
- if (null != ename && ename.equals(name))
- {
- String nname = (String) m_entities.elementAt(i
- + ENTITY_FIELD_NOTATIONNAME);
+ if (null != ename && ename.equals(name)) {
+ String nname = m_entities.get(i + ENTITY_FIELD_NOTATIONNAME);
- if (null != nname)
- {
-
+ if (null != nname) {
// The draft says: "The XSLT processor may use the public
// identifier to generate a URI for the entity instead of the URI
// specified in the system identifier. If the XSLT processor does
@@ -1118,11 +1068,10 @@
// the resource containing the entity declaration as the base
// URI [RFC2396]."
// So I'm falling a bit short here.
- url = (String) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID);
+ url = m_entities.get(i + ENTITY_FIELD_SYSTEMID);
- if (null == url)
- {
- url = (String) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID);
+ if (null == url) {
+ url = m_entities.get(i + ENTITY_FIELD_PUBLICID);
}
}
@@ -1400,26 +1349,18 @@
*
* @return The prefix if there is one, or null.
*/
- public String getPrefix(String qname, String uri)
- {
-
+ public String getPrefix(String qname, String uri) {
String prefix;
int uriIndex = -1;
- if (null != uri && uri.length() > 0)
- {
-
- do
- {
+ if (null != uri && uri.length() > 0) {
+ do {
uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex);
- } while ( (uriIndex & 0x01) == 0);
+ } while ((uriIndex & 0x01) == 0);
- if (uriIndex >= 0)
- {
- prefix = (String) m_prefixMappings.elementAt(uriIndex - 1);
- }
- else if (null != qname)
- {
+ if (uriIndex >= 0) {
+ prefix = m_prefixMappings.elementAt(uriIndex - 1);
+ } else if (null != qname) {
int indexOfNSSep = qname.indexOf(':');
if (qname.equals("xmlns"))
@@ -1429,33 +1370,24 @@
else
prefix = (indexOfNSSep > 0)
? qname.substring(0, indexOfNSSep) : null;
- }
- else
- {
+ } else {
prefix = null;
}
- }
- else if (null != qname)
- {
+ } else if (null != qname) {
int indexOfNSSep = qname.indexOf(':');
- if (indexOfNSSep > 0)
- {
+ if (indexOfNSSep > 0) {
if (qname.startsWith("xmlns:"))
prefix = qname.substring(indexOfNSSep + 1);
else
prefix = qname.substring(0, indexOfNSSep);
- }
- else
- {
+ } else {
if (qname.equals("xmlns"))
prefix = "";
else
prefix = null;
}
- }
- else
- {
+ } else {
prefix = null;
}
@@ -1470,38 +1402,31 @@
*
* @return The prefix if there is one, or null.
*/
- public int getIdForNamespace(String uri)
- {
-
+ public int getIdForNamespace(String uri) {
return m_valuesOrPrefixes.stringToIndex(uri);
-
}
- /**
+ /**
* Get a prefix either from the qname or from the uri mapping, or just make
* one up!
*
* @return The prefix if there is one, or null.
*/
- public String getNamespaceURI(String prefix)
- {
-
+ public String getNamespaceURI(String prefix) {
String uri = "";
int prefixIndex = m_contextIndexes.peek() - 1 ;
- if(null == prefix)
+ if (null == prefix) {
prefix = "";
+ }
- do
- {
- prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex);
- } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01);
+ do {
+ prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex);
+ } while ((prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01);
- if (prefixIndex > -1)
- {
- uri = (String) m_prefixMappings.elementAt(prefixIndex + 1);
- }
-
+ if (prefixIndex > -1) {
+ uri = m_prefixMappings.elementAt(prefixIndex + 1);
+ }
return uri;
}
@@ -1578,7 +1503,7 @@
* default behaviour.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.EntityResolver#resolveEntity
+ * @see EntityResolver#resolveEntity
*
* @throws SAXException
*/
@@ -1605,7 +1530,7 @@
* @param systemId The notation system identifier.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.DTDHandler#notationDecl
+ * @see DTDHandler#notationDecl
*
* @throws SAXException
*/
@@ -1630,41 +1555,35 @@
* @param notationName The name of the associated notation.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ * @see DTDHandler#unparsedEntityDecl
*
* @throws SAXException
*/
- public void unparsedEntityDecl(
- String name, String publicId, String systemId, String notationName)
- throws SAXException
+ public void unparsedEntityDecl(String name, String publicId, String systemId,
+ String notationName) throws SAXException
{
-
- if (null == m_entities)
- {
- m_entities = new Vector();
+ if (null == m_entities) {
+ m_entities = new ArrayList<>();
}
- try
- {
+ try {
systemId = SystemIDResolver.getAbsoluteURI(systemId,
getDocumentBaseURI());
- }
- catch (Exception e)
- {
- throw new org.xml.sax.SAXException(e);
+ } catch (Exception e) {
+ throw new SAXException(e);
}
// private static final int ENTITY_FIELD_PUBLICID = 0;
- m_entities.addElement(publicId);
+ m_entities.add(publicId);
// private static final int ENTITY_FIELD_SYSTEMID = 1;
- m_entities.addElement(systemId);
+ m_entities.add(systemId);
// private static final int ENTITY_FIELD_NOTATIONNAME = 2;
- m_entities.addElement(notationName);
+ m_entities.add(notationName);
// private static final int ENTITY_FIELD_NAME = 3;
- m_entities.addElement(name);
+ m_entities.add(name);
}
////////////////////////////////////////////////////////////////////
@@ -1679,8 +1598,8 @@
* with other document events.</p>
*
* @param locator A locator for all SAX document events.
- * @see org.xml.sax.ContentHandler#setDocumentLocator
- * @see org.xml.sax.Locator
+ * @see ContentHandler#setDocumentLocator
+ * @see Locator
*/
public void setDocumentLocator(Locator locator)
{
@@ -1693,7 +1612,7 @@
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#startDocument
+ * @see ContentHandler#startDocument
*/
public void startDocument() throws SAXException
{
@@ -1716,7 +1635,7 @@
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#endDocument
+ * @see ContentHandler#endDocument
*/
public void endDocument() throws SAXException
{
@@ -1754,7 +1673,7 @@
* @param uri The Namespace URI mapped to the prefix.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#startPrefixMapping
+ * @see ContentHandler#startPrefixMapping
*/
public void startPrefixMapping(String prefix, String uri)
throws SAXException
@@ -1780,7 +1699,7 @@
* @param prefix The Namespace prefix being declared.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#endPrefixMapping
+ * @see ContentHandler#endPrefixMapping
*/
public void endPrefixMapping(String prefix) throws SAXException
{
@@ -1815,16 +1734,13 @@
* @return true if the declaration has already been declared in the
* current context.
*/
- protected boolean declAlreadyDeclared(String prefix)
- {
-
+ protected boolean declAlreadyDeclared(String prefix) {
int startDecls = m_contextIndexes.peek();
- java.util.Vector prefixMappings = m_prefixMappings;
+ Vector<String> prefixMappings = m_prefixMappings;
int nDecls = prefixMappings.size();
- for (int i = startDecls; i < nDecls; i += 2)
- {
- String prefixDecl = (String) prefixMappings.elementAt(i);
+ for (int i = startDecls; i < nDecls; i += 2) {
+ String prefixDecl = prefixMappings.elementAt(i);
if (prefixDecl == null)
continue;
@@ -1836,7 +1752,7 @@
return false;
}
- boolean m_pastFirstElement=false;
+ boolean m_pastFirstElement=false;
/**
* Receive notification of the start of an element.
@@ -1857,35 +1773,38 @@
* @param attributes The specified or defaulted attributes.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#startElement
+ * @see ContentHandler#startElement
*/
- public void startElement(
- String uri, String localName, String qName, Attributes attributes)
- throws SAXException
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException
{
- if (DEBUG)
- {
- System.out.println("startElement: uri: " + uri + ", localname: "
- + localName + ", qname: "+qName+", atts: " + attributes);
+ if (DEBUG) {
+ System.out.println("startElement: uri: " + uri +
+ ", localname: " + localName +
+ ", qname: "+qName+", atts: " + attributes);
- boolean DEBUG_ATTRS=true;
- if(DEBUG_ATTRS & attributes!=null)
- {
- int n = attributes.getLength();
- if(n==0)
- System.out.println("\tempty attribute list");
- else for (int i = 0; i < n; i++)
- System.out.println("\t attr: uri: " + attributes.getURI(i) +
- ", localname: " + attributes.getLocalName(i) +
- ", qname: " + attributes.getQName(i) +
- ", type: " + attributes.getType(i) +
- ", value: " + attributes.getValue(i)
- );
- }
- }
+ boolean DEBUG_ATTRS=true;
+ if (DEBUG_ATTRS & attributes!=null) {
+ int n = attributes.getLength();
+ if (n==0) {
+ System.out.println("\tempty attribute list");
+ } else for (int i = 0; i < n; i++) {
+ System.out.println("\t attr: uri: " + attributes.getURI(i) +
+ ", localname: " + attributes.getLocalName(i) +
+ ", qname: " + attributes.getQName(i) +
+ ", type: " + attributes.getType(i) +
+ ", value: " + attributes.getValue(i));
+ }
+ }
+ }
charactersFlush();
+ if ((localName == null || localName.isEmpty()) &&
+ (uri == null || uri.isEmpty())) {
+ localName = qName;
+ }
+
int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
String prefix = getPrefix(qName, uri);
int prefixIndex = (null != prefix)
@@ -1894,20 +1813,18 @@
int elemNode = addNode(DTM.ELEMENT_NODE, exName,
m_parents.peek(), m_previous, prefixIndex, true);
- if(m_indexing)
+ if (m_indexing)
indexNode(exName, elemNode);
-
m_parents.push(elemNode);
int startDecls = m_contextIndexes.peek();
int nDecls = m_prefixMappings.size();
int prev = DTM.NULL;
- if(!m_pastFirstElement)
- {
+ if (!m_pastFirstElement) {
// SPECIAL CASE: Implied declaration at root element
- prefix="xml";
+ prefix = "xml";
String declURL = "http://www.w3.org/XML/1998/namespace";
exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
int val = m_valuesOrPrefixes.stringToIndex(declURL);
@@ -1916,14 +1833,13 @@
m_pastFirstElement=true;
}
- for (int i = startDecls; i < nDecls; i += 2)
- {
- prefix = (String) m_prefixMappings.elementAt(i);
+ for (int i = startDecls; i < nDecls; i += 2) {
+ prefix = m_prefixMappings.elementAt(i);
if (prefix == null)
continue;
- String declURL = (String) m_prefixMappings.elementAt(i + 1);
+ String declURL = m_prefixMappings.elementAt(i + 1);
exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
@@ -1935,8 +1851,7 @@
int n = attributes.getLength();
- for (int i = 0; i < n; i++)
- {
+ for (int i = 0; i < n; i++) {
String attrUri = attributes.getURI(i);
String attrQName = attributes.getQName(i);
String valString = attributes.getValue(i);
@@ -1947,17 +1862,13 @@
String attrLocalName = attributes.getLocalName(i);
- if ((null != attrQName)
- && (attrQName.equals("xmlns")
- || attrQName.startsWith("xmlns:")))
- {
+ if ((null != attrQName) &&
+ (attrQName.equals("xmlns") || attrQName.startsWith("xmlns:"))) {
if (declAlreadyDeclared(prefix))
continue; // go to the next attribute.
nodeType = DTM.NAMESPACE_NODE;
- }
- else
- {
+ } else {
nodeType = DTM.ATTRIBUTE_NODE;
if (attributes.getType(i).equalsIgnoreCase("ID"))
@@ -1966,15 +1877,13 @@
// Bit of a hack... if somehow valString is null, stringToIndex will
// return -1, which will make things very unhappy.
- if(null == valString)
+ if (null == valString)
valString = "";
int val = m_valuesOrPrefixes.stringToIndex(valString);
//String attrLocalName = attributes.getLocalName(i);
- if (null != prefix)
- {
-
+ if (null != prefix) {
prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
int dataIndex = m_data.size();
@@ -1993,8 +1902,7 @@
if (DTM.NULL != prev)
m_nextsib.setElementAt(DTM.NULL,prev);
- if (null != m_wsfilter)
- {
+ if (null != m_wsfilter) {
short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
? getShouldStripWhitespace()
@@ -2026,7 +1934,7 @@
* empty string if qualified names are not available.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#endElement
+ * @see ContentHandler#endElement
*/
public void endElement(String uri, String localName, String qName)
throws SAXException
@@ -2074,7 +1982,7 @@
* character array.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#characters
+ * @see ContentHandler#characters
*/
public void characters(char ch[], int start, int length) throws SAXException
{
@@ -2109,7 +2017,7 @@
* character array.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#ignorableWhitespace
+ * @see ContentHandler#ignorableWhitespace
*/
public void ignorableWhitespace(char ch[], int start, int length)
throws SAXException
@@ -2133,7 +2041,7 @@
* none is supplied.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#processingInstruction
+ * @see ContentHandler#processingInstruction
*/
public void processingInstruction(String target, String data)
throws SAXException
@@ -2163,7 +2071,7 @@
* @param name The name of the skipped entity.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#processingInstruction
+ * @see ContentHandler#processingInstruction
*/
public void skippedEntity(String name) throws SAXException
{
@@ -2187,8 +2095,8 @@
* @param e The warning information encoded as an exception.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ErrorHandler#warning
- * @see org.xml.sax.SAXParseException
+ * @see ErrorHandler#warning
+ * @see SAXParseException
*/
public void warning(SAXParseException e) throws SAXException
{
@@ -2208,8 +2116,8 @@
* @param e The warning information encoded as an exception.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ErrorHandler#warning
- * @see org.xml.sax.SAXParseException
+ * @see ErrorHandler#warning
+ * @see SAXParseException
*/
public void error(SAXParseException e) throws SAXException
{
@@ -2230,8 +2138,8 @@
* @param e The error information encoded as an exception.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ErrorHandler#fatalError
- * @see org.xml.sax.SAXParseException
+ * @see ErrorHandler#fatalError
+ * @see SAXParseException
*/
public void fatalError(SAXParseException e) throws SAXException
{
@@ -2299,7 +2207,7 @@
* @param value The replacement text of the entity.
* @throws SAXException The application may raise an exception.
* @see #externalEntityDecl
- * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ * @see DTDHandler#unparsedEntityDecl
*/
public void internalEntityDecl(String name, String value)
throws SAXException
@@ -2321,7 +2229,7 @@
* @param systemId The declared system identifier of the entity.
* @throws SAXException The application may raise an exception.
* @see #internalEntityDecl
- * @see org.xml.sax.DTDHandler#unparsedEntityDecl
+ * @see DTDHandler#unparsedEntityDecl
*/
public void externalEntityDecl(
String name, String publicId, String systemId) throws SAXException
@@ -2386,15 +2294,15 @@
* properly nested within start/end entity events.</p>
*
* <p>Note that skipped entities will be reported through the
- * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
+ * {@link ContentHandler#skippedEntity skippedEntity}
* event, which is part of the ContentHandler interface.</p>
*
* @param name The name of the entity. If it is a parameter
* entity, the name will begin with '%'.
* @throws SAXException The application may raise an exception.
* @see #endEntity
- * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
- * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
+ * @see DeclHandler#internalEntityDecl
+ * @see DeclHandler#externalEntityDecl
*/
public void startEntity(String name) throws SAXException
{
@@ -2419,7 +2327,7 @@
* Report the start of a CDATA section.
*
* <p>The contents of the CDATA section will be reported through
- * the regular {@link org.xml.sax.ContentHandler#characters
+ * the regular {@link ContentHandler#characters
* characters} event.</p>
*
* @throws SAXException The application may raise an exception.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,13 +1,13 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 1999-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@@ -17,13 +17,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: SAX2DTM2.java,v 1.2.4.1 2005/09/15 08:15:12 suresh_emailid Exp $
- */
+
package com.sun.org.apache.xml.internal.dtm.ref.sax2dtm;
-import com.sun.org.apache.xml.internal.dtm.*;
-import com.sun.org.apache.xml.internal.dtm.ref.*;
+import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
+import com.sun.org.apache.xml.internal.dtm.DTMException;
+import com.sun.org.apache.xml.internal.dtm.DTMManager;
+import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
+import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
+import com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable;
+import com.sun.org.apache.xml.internal.dtm.ref.ExtendedType;
import com.sun.org.apache.xml.internal.utils.FastStringBuffer;
import com.sun.org.apache.xml.internal.utils.XMLString;
import com.sun.org.apache.xml.internal.utils.XMLStringDefault;
@@ -31,11 +35,12 @@
import com.sun.org.apache.xml.internal.res.XMLMessages;
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
-
+import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector;
+import java.util.ArrayList;
import javax.xml.transform.Source;
-import java.util.Vector;
-import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector;
-import org.xml.sax.*;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
/**
* SAX2DTM2 is an optimized version of SAX2DTM which is used in non-incremental situation.
@@ -53,10 +58,6 @@
* The design of SAX2DTM2 may limit its extensibilty. If you have a reason to extend the
* SAX2DTM model, please extend from SAX2DTM instead of this class.
* <p>
- * TODO: This class is currently only used by XSLTC. We need to investigate the possibility
- * of also using it in Xalan-J Interpretive. Xalan's performance is likely to get an instant
- * boost if we use SAX2DTM2 instead of SAX2DTM in non-incremental case.
- * <p>
* %MK% The code in this class is critical to the XSLTC_DTM performance. Be very careful
* when making changes here!
*/
@@ -87,11 +88,10 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
_currentNode = (node == DTM.NULL) ? DTM.NULL
: _firstch2(makeNodeIdentity(node));
@@ -108,8 +108,7 @@
* @return The next node handle in the iteration, or END if no more
* are available.
*/
- public int next()
- {
+ public int next() {
if (_currentNode != NULL) {
int node = _currentNode;
_currentNode = _nextsib2(node);
@@ -139,13 +138,11 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ public DTMAxisIterator setStartNode(int node) {
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
if (node != DTM.NULL)
@@ -229,8 +226,7 @@
*
* @param nodeType The extended type ID being requested.
*/
- public TypedChildrenIterator(int nodeType)
- {
+ public TypedChildrenIterator(int nodeType) {
_nodeType = nodeType;
}
@@ -242,17 +238,14 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ public DTMAxisIterator setStartNode(int node) {
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
- _currentNode = (node == DTM.NULL)
- ? DTM.NULL
- : _firstch2(makeNodeIdentity(_startNode));
+ _currentNode = (node == DTM.NULL) ? DTM.NULL :
+ _firstch2(makeNodeIdentity(_startNode));
return resetPosition();
}
@@ -265,8 +258,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
+ public int next() {
int node = _currentNode;
if (node == DTM.NULL)
return DTM.NULL;
@@ -301,14 +293,12 @@
_currentNode = _nextsib2(node);
return returnNode(makeNodeHandle(node));
}
-
}
/**
* Return the node at the given position.
*/
- public int getNodeByPosition(int position)
- {
+ public int getNodeByPosition(int position) {
if (position <= 0)
return DTM.NULL;
@@ -327,8 +317,7 @@
node = _nextsib2(node);
}
return NULL;
- }
- else {
+ } else {
while (node != DTM.NULL) {
if (_exptype2(node) >= DTM.NTYPES) {
pos++;
@@ -415,13 +404,11 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ public DTMAxisIterator setStartNode(int node) {
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
_currentNode = makeNodeIdentity(node);
@@ -436,8 +423,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
+ public int next() {
_currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
: _nextsib2(_currentNode);
return returnNode(makeNodeHandle(_currentNode));
@@ -460,8 +446,7 @@
*
* @param type The extended type ID being requested.
*/
- public TypedFollowingSiblingIterator(int type)
- {
+ public TypedFollowingSiblingIterator(int type) {
_nodeType = type;
}
@@ -470,8 +455,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
+ public int next() {
if (_currentNode == DTM.NULL) {
return DTM.NULL;
}
@@ -481,8 +465,7 @@
if (nodeType != DTM.ELEMENT_NODE) {
while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) != nodeType) {}
- }
- else {
+ } else {
while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) < DTM.NTYPES) {}
}
@@ -498,8 +481,7 @@
/**
* Iterator that returns attribute nodes (of what nodes?)
*/
- public final class AttributeIterator extends InternalAxisIteratorBase
- {
+ public final class AttributeIterator extends InternalAxisIteratorBase {
// assumes caller will pass element nodes
@@ -511,13 +493,11 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ public DTMAxisIterator setStartNode(int node) {
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
_currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
@@ -532,9 +512,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
-
+ public int next() {
final int node = _currentNode;
if (node != NULL) {
@@ -561,8 +539,7 @@
*
* @param nodeType The extended type ID that is requested.
*/
- public TypedAttributeIterator(int nodeType)
- {
+ public TypedAttributeIterator(int nodeType) {
_nodeType = nodeType;
}
@@ -576,14 +553,10 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
- if (_isRestartable)
- {
+ public DTMAxisIterator setStartNode(int node) {
+ if (_isRestartable) {
_startNode = node;
-
_currentNode = getTypedAttribute(node, _nodeType);
-
return resetPosition();
}
@@ -595,9 +568,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
-
+ public int next() {
final int node = _currentNode;
// singleton iterator, since there can only be one attribute of
@@ -624,8 +595,7 @@
*
* @return true.
*/
- public boolean isReverse()
- {
+ public boolean isReverse() {
return true;
}
@@ -637,30 +607,25 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(int node)
- {
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ public DTMAxisIterator setStartNode(int node) {
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
- if (_isRestartable)
- {
+ if (_isRestartable) {
_startNode = node;
node = _startNodeID = makeNodeIdentity(node);
- if(node == NULL)
- {
+ if(node == NULL) {
_currentNode = node;
return resetPosition();
}
int type = _type2(node);
- if(ExpandedNameTable.ATTRIBUTE == type
- || ExpandedNameTable.NAMESPACE == type )
+ if (ExpandedNameTable.ATTRIBUTE == type ||
+ ExpandedNameTable.NAMESPACE == type)
{
_currentNode = node;
- }
- else
- {
+ } else {
// Be careful to handle the Document node properly
_currentNode = _parent2(node);
if(NULL!=_currentNode)
@@ -680,18 +645,12 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
-
- if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
- {
+ public int next() {
+ if (_currentNode == _startNodeID || _currentNode == DTM.NULL) {
return NULL;
- }
- else
- {
+ } else {
final int node = _currentNode;
_currentNode = _nextsib2(node);
-
return returnNode(makeNodeHandle(node));
}
}
@@ -714,8 +673,7 @@
*
* @param type The extended type ID being requested.
*/
- public TypedPrecedingSiblingIterator(int type)
- {
+ public TypedPrecedingSiblingIterator(int type) {
_nodeType = type;
}
@@ -724,8 +682,7 @@
*
* @return The next node handle in the iteration, or END.
*/
- public int next()
- {
+ public int next() {
int node = _currentNode;
final int nodeType = _nodeType;
@@ -735,8 +692,7 @@
while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) {
node = _nextsib2(node);
}
- }
- else {
+ } else {
while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) {
node = _nextsib2(node);
}
@@ -745,8 +701,7 @@
if (node == DTM.NULL || node == startNodeID) {
_currentNode = NULL;
return NULL;
- }
- else {
+ } else {
_currentNode = _nextsib2(node);
return returnNode(makeNodeHandle(node));
}
@@ -755,8 +710,7 @@
/**
* Return the index of the last node in this iterator.
*/
- public int getLast()
- {
+ public int getLast() {
if (_last != -1)
return _last;
@@ -774,8 +728,7 @@
}
node = _nextsib2(node);
}
- }
- else {
+ } else {
while (node != NULL && node != startNodeID) {
if (_exptype2(node) >= DTM.NTYPES) {
last++;
@@ -860,7 +813,7 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
@@ -1799,9 +1752,7 @@
// %OPT% These values are unlikely to be equal. Storing
// them in a plain Vector is more efficient than storing in the
// DTMStringPool because we can save the cost for hash calculation.
- //
- // %REVISIT% Do we need a custom class (e.g. StringVector) here?
- protected Vector m_values;
+ protected ArrayList<String> m_values;
// The current index into the m_values Vector.
private int m_valueIndex = 0;
@@ -1881,9 +1832,8 @@
m_buildIdIndex = buildIdIndex;
// Some documents do not have attribute nodes. That is why
- // we set the initial size of this Vector to be small and set
- // the increment to a bigger number.
- m_values = new Vector(32, 512);
+ // we set the initial size of this ArrayList to be small.
+ m_values = new ArrayList<>(32);
m_maxNodeIndex = 1 << DTMManager.IDENT_DTM_NODE_BITS;
@@ -1953,10 +1903,7 @@
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
- public final int _firstch2(int identity)
- {
- //return m_firstch.elementAt(identity);
-
+ public final int _firstch2(int identity) {
if (identity < m_blocksize)
return m_firstch_map0[identity];
else
@@ -1969,10 +1916,7 @@
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
- public final int _parent2(int identity)
- {
- //return m_parent.elementAt(identity);
-
+ public final int _parent2(int identity) {
if (identity < m_blocksize)
return m_parent_map0[identity];
else
@@ -1985,9 +1929,7 @@
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
- public final int _type2(int identity)
- {
- //int eType = _exptype2(identity);
+ public final int _type2(int identity) {
int eType;
if (identity < m_blocksize)
eType = m_exptype_map0[identity];
@@ -2006,12 +1948,9 @@
* <p>This one is only used by DOMAdapter.getExpandedTypeID(int), which
* is mostly called from the compiled translets.
*/
- public final int getExpandedTypeID2(int nodeHandle)
- {
+ public final int getExpandedTypeID2(int nodeHandle) {
int nodeID = makeNodeIdentity(nodeHandle);
- //return (nodeID != NULL) ? _exptype2(nodeID) : NULL;
-
if (nodeID != NULL) {
if (nodeID < m_blocksize)
return m_exptype_map0[nodeID];
@@ -2026,12 +1965,10 @@
* END of DTM base accessor interfaces
*************************************************************************/
-
/**
* Return the node type from the expanded type
*/
- public final int _exptype2Type(int exptype)
- {
+ public final int _exptype2Type(int exptype) {
if (NULL != exptype)
return m_extendedTypes[exptype].getNodeType();
else
@@ -2046,16 +1983,14 @@
*
* @return The prefix if there is one, or null.
*/
- public int getIdForNamespace(String uri)
- {
+ public int getIdForNamespace(String uri) {
int index = m_values.indexOf(uri);
- if (index < 0)
- {
- m_values.addElement(uri);
+ if (index < 0) {
+ m_values.add(uri);
return m_valueIndex++;
+ } else {
+ return index;
}
- else
- return index;
}
/**
@@ -2079,15 +2014,25 @@
* @param attributes The specified or defaulted attributes.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#startElement
+ * @see ContentHandler#startElement
*/
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException
{
-
charactersFlush();
- int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
+ // in case URI and localName are empty, the input is not using the
+ // namespaces feature. Then we should take the part after the last
+ // colon of qName as localName (strip all namespace prefixes)
+ if ((uri == null || uri.isEmpty()) &&
+ (localName == null || localName.isEmpty()))
+ {
+ final int colon = qName.lastIndexOf(':');
+ localName = (colon > -1) ? qName.substring(colon + 1) : qName;
+ }
+
+ int exName = m_expandedNameTable.getExpandedTypeID(uri, localName,
+ DTM.ELEMENT_NODE);
int prefixIndex = (qName.length() != localName.length())
? m_valuesOrPrefixes.stringToIndex(qName) : 0;
@@ -2095,7 +2040,7 @@
int elemNode = addNode(DTM.ELEMENT_NODE, exName,
m_parents.peek(), m_previous, prefixIndex, true);
- if(m_indexing)
+ if (m_indexing)
indexNode(exName, elemNode);
m_parents.push(elemNode);
@@ -2104,31 +2049,31 @@
int nDecls = m_prefixMappings.size();
String prefix;
- if(!m_pastFirstElement)
- {
+ if (!m_pastFirstElement) {
// SPECIAL CASE: Implied declaration at root element
- prefix="xml";
+ prefix = "xml";
String declURL = "http://www.w3.org/XML/1998/namespace";
- exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
- m_values.addElement(declURL);
+ exName = m_expandedNameTable.getExpandedTypeID(null, prefix,
+ DTM.NAMESPACE_NODE);
+ m_values.add(declURL);
int val = m_valueIndex++;
addNode(DTM.NAMESPACE_NODE, exName, elemNode,
DTM.NULL, val, false);
m_pastFirstElement=true;
}
- for (int i = startDecls; i < nDecls; i += 2)
- {
- prefix = (String) m_prefixMappings.elementAt(i);
+ for (int i = startDecls; i < nDecls; i += 2) {
+ prefix = m_prefixMappings.elementAt(i);
if (prefix == null)
continue;
- String declURL = (String) m_prefixMappings.elementAt(i + 1);
-
- exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
-
- m_values.addElement(declURL);
+ String declURL = m_prefixMappings.elementAt(i + 1);
+
+ exName = m_expandedNameTable.getExpandedTypeID(null, prefix,
+ DTM.NAMESPACE_NODE);
+
+ m_values.add(declURL);
int val = m_valueIndex++;
addNode(DTM.NAMESPACE_NODE, exName, elemNode, DTM.NULL, val, false);
@@ -2136,28 +2081,37 @@
int n = attributes.getLength();
- for (int i = 0; i < n; i++)
- {
+ for (int i = 0; i < n; i++) {
String attrUri = attributes.getURI(i);
+ String attrLocalName = attributes.getLocalName(i);
String attrQName = attributes.getQName(i);
String valString = attributes.getValue(i);
+ // in case URI and localName are empty, the input is not using the
+ // namespaces feature. Then we should take the part after the last
+ // colon of qName as localName (strip all namespace prefixes)
+ // When the URI is empty but localName has colons then we can also
+ // assume non namespace aware and prefixes can be stripped
+ if (attrUri == null || attrUri.isEmpty()) {
+ if (attrLocalName == null || attrLocalName.isEmpty()) {
+ final int colon = attrQName.lastIndexOf(':');
+ attrLocalName = (colon > -1) ? attrQName.substring(colon + 1) : attrQName;
+ } else {
+ final int colon = attrLocalName.lastIndexOf(':');
+ attrLocalName = (colon > -1) ? attrLocalName.substring(colon + 1) : attrLocalName;
+ }
+ }
+
int nodeType;
-
- String attrLocalName = attributes.getLocalName(i);
-
- if ((null != attrQName)
- && (attrQName.equals("xmlns")
- || attrQName.startsWith("xmlns:")))
+ if ((null != attrQName) &&
+ (attrQName.equals("xmlns") || attrQName.startsWith("xmlns:")))
{
prefix = getPrefix(attrQName, attrUri);
if (declAlreadyDeclared(prefix))
continue; // go to the next attribute.
nodeType = DTM.NAMESPACE_NODE;
- }
- else
- {
+ } else {
nodeType = DTM.ATTRIBUTE_NODE;
if (m_buildIdIndex && attributes.getType(i).equalsIgnoreCase("ID"))
@@ -2166,36 +2120,31 @@
// Bit of a hack... if somehow valString is null, stringToIndex will
// return -1, which will make things very unhappy.
- if(null == valString)
+ if (null == valString)
valString = "";
- m_values.addElement(valString);
+ m_values.add(valString);
int val = m_valueIndex++;
- if (attrLocalName.length() != attrQName.length())
- {
-
+ if (attrLocalName.length() != attrQName.length()) {
prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
-
int dataIndex = m_data.size();
-
m_data.addElement(prefixIndex);
m_data.addElement(val);
-
val = -dataIndex;
}
- exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
- addNode(nodeType, exName, elemNode, DTM.NULL, val,
- false);
+ exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName,
+ nodeType);
+ addNode(nodeType, exName, elemNode, DTM.NULL, val, false);
}
- if (null != m_wsfilter)
- {
- short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
- boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
- ? getShouldStripWhitespace()
- : (DTMWSFilter.STRIP == wsv);
+ if (null != m_wsfilter) {
+ short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode),
+ this);
+ boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) ?
+ getShouldStripWhitespace() :
+ (DTMWSFilter.STRIP == wsv);
pushShouldStripWhitespace(shouldStrip);
}
@@ -2223,7 +2172,7 @@
* empty string if qualified names are not available.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#endElement
+ * @see ContentHandler#endElement
*/
public void endElement(String uri, String localName, String qName)
throws SAXException
@@ -2257,9 +2206,7 @@
* @param length The number of characters to use from the array.
* @throws SAXException The application may raise an exception.
*/
- public void comment(char ch[], int start, int length) throws SAXException
- {
-
+ public void comment(char ch[], int start, int length) throws SAXException {
if (m_insideDTD) // ignore comments if we're inside the DTD
return;
@@ -2267,7 +2214,7 @@
// %OPT% Saving the comment string in a Vector has a lower cost than
// saving it in DTMStringPool.
- m_values.addElement(new String(ch, start, length));
+ m_values.add(new String(ch, start, length));
int dataIndex = m_valueIndex++;
m_previous = addNode(DTM.COMMENT_NODE, DTM.COMMENT_NODE,
@@ -2279,13 +2226,10 @@
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#startDocument
+ * @see ContentHandler#startDocument
*/
- public void startDocument() throws SAXException
- {
-
- int doc = addNode(DTM.DOCUMENT_NODE,
- DTM.DOCUMENT_NODE,
+ public void startDocument() throws SAXException {
+ int doc = addNode(DTM.DOCUMENT_NODE, DTM.DOCUMENT_NODE,
DTM.NULL, DTM.NULL, 0, true);
m_parents.push(doc);
@@ -2299,10 +2243,9 @@
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#endDocument
+ * @see ContentHandler#endDocument
*/
- public void endDocument() throws SAXException
- {
+ public void endDocument() throws SAXException {
super.endDocument();
// Add a NULL entry to the end of the node arrays as
@@ -2334,16 +2277,15 @@
* @return The index identity of the node that was added.
*/
protected final int addNode(int type, int expandedTypeID,
- int parentIndex, int previousSibling,
- int dataOrPrefix, boolean canHaveFirstChild)
+ int parentIndex, int previousSibling,
+ int dataOrPrefix, boolean canHaveFirstChild)
{
// Common to all nodes:
int nodeIndex = m_size++;
// Have we overflowed a DTM Identity's addressing range?
//if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
- if (nodeIndex == m_maxNodeIndex)
- {
+ if (nodeIndex == m_maxNodeIndex) {
addNewDTMID(nodeIndex);
m_maxNodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);
}
@@ -2366,8 +2308,7 @@
// is called, to handle successive characters() events.
// Special handling by type: Declare namespaces, attach first child
- switch(type)
- {
+ switch(type) {
case DTM.NAMESPACE_NODE:
declareNamespaceInContext(parentIndex,nodeIndex);
break;
@@ -2376,8 +2317,7 @@
default:
if (DTM.NULL != previousSibling) {
m_nextsib.setElementAt(nodeIndex,previousSibling);
- }
- else if (DTM.NULL != parentIndex) {
+ } else if (DTM.NULL != parentIndex) {
m_firstch.setElementAt(nodeIndex,parentIndex);
}
break;
@@ -2390,16 +2330,12 @@
* Check whether accumulated text should be stripped; if not,
* append the appropriate flavor of text/cdata node.
*/
- protected final void charactersFlush()
- {
-
- if (m_textPendingStart >= 0) // -1 indicates no-text-in-progress
- {
+ protected final void charactersFlush() {
+ if (m_textPendingStart >= 0) { // -1 indicates no-text-in-progress
int length = m_chars.size() - m_textPendingStart;
boolean doStrip = false;
- if (getShouldStripWhitespace())
- {
+ if (getShouldStripWhitespace()) {
doStrip = m_chars.isWhitespace(m_textPendingStart, length);
}
@@ -2412,19 +2348,19 @@
// If the offset and length do not exceed the given limits
// (offset < 2^21 and length < 2^10), then save both the offset
// and length in a bitwise encoded value.
- if (length <= TEXT_LENGTH_MAX
- && m_textPendingStart <= TEXT_OFFSET_MAX) {
+ if (length <= TEXT_LENGTH_MAX &&
+ m_textPendingStart <= TEXT_OFFSET_MAX) {
m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
- m_parents.peek(), m_previous,
- length + (m_textPendingStart << TEXT_LENGTH_BITS),
- false);
+ m_parents.peek(), m_previous,
+ length + (m_textPendingStart << TEXT_LENGTH_BITS),
+ false);
} else {
// Store offset and length in the m_data array if one exceeds
// the given limits. Use a negative dataIndex as an indication.
int dataIndex = m_data.size();
m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
- m_parents.peek(), m_previous, -dataIndex, false);
+ m_parents.peek(), m_previous, -dataIndex, false);
m_data.addElement(m_textPendingStart);
m_data.addElement(length);
@@ -2452,7 +2388,7 @@
* none is supplied.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
- * @see org.xml.sax.ContentHandler#processingInstruction
+ * @see ContentHandler#processingInstruction
*/
public void processingInstruction(String target, String data)
throws SAXException
@@ -2467,7 +2403,7 @@
-dataIndex, false);
m_data.addElement(m_valuesOrPrefixes.stringToIndex(target));
- m_values.addElement(data);
+ m_values.add(data);
m_data.addElement(m_valueIndex++);
}
@@ -2865,9 +2801,9 @@
}
if (m_xstrf != null)
- return m_xstrf.newstr((String)m_values.elementAt(dataIndex));
+ return m_xstrf.newstr(m_values.get(dataIndex));
else
- return new XMLStringDefault((String)m_values.elementAt(dataIndex));
+ return new XMLStringDefault(m_values.get(dataIndex));
}
}
@@ -2966,7 +2902,7 @@
dataIndex = m_data.elementAt(dataIndex + 1);
}
- return (String)m_values.elementAt(dataIndex);
+ return m_values.get(dataIndex);
}
}
@@ -3106,7 +3042,7 @@
dataIndex = m_data.elementAt(dataIndex + 1);
}
- String str = (String)m_values.elementAt(dataIndex);
+ String str = m_values.get(dataIndex);
if(normalize)
FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
@@ -3160,7 +3096,7 @@
dataIndex = m_data.elementAt(dataIndex + 1);
}
- return (String)m_values.elementAt(dataIndex);
+ return m_values.get(dataIndex);
}
}
@@ -3202,8 +3138,7 @@
if (uri.length() == 0) {
handler.startElement(name);
return name;
- }
- else {
+ } else {
int qnameIndex = m_dataOrQName.elementAt(nodeID);
if (qnameIndex == 0) {
@@ -3223,14 +3158,12 @@
String prefix;
if (prefixIndex > 0) {
prefix = qName.substring(0, prefixIndex);
- }
- else {
+ } else {
prefix = null;
}
handler.namespaceAfterStartElement(prefix, uri);
return qName;
}
-
}
/**
@@ -3285,7 +3218,7 @@
dataIndex = m_data.elementAt(dataIndex + 1);
}
- String nodeValue = (String)m_values.elementAt(dataIndex);
+ String nodeValue = m_values.get(dataIndex);
handler.namespaceAfterStartElement(nodeName, nodeValue);
@@ -3335,7 +3268,6 @@
}
-
/**
* Copy an Attribute node to a SerializationHandler
*
@@ -3347,14 +3279,6 @@
SerializationHandler handler)
throws SAXException
{
- /*
- final String uri = getNamespaceName(node);
- if (uri.length() != 0) {
- final String prefix = getPrefix(node);
- handler.namespaceAfterStartElement(prefix, uri);
- }
- handler.addAttribute(getNodeName(node), getNodeValue(node));
- */
final ExtendedType extType = m_extendedTypes[exptype];
final String uri = extType.getNamespace();
final String localName = extType.getLocalName();
@@ -3377,7 +3301,7 @@
}
String nodeName = (prefix != null) ? qname : localName;
- String nodeValue = (String)m_values.elementAt(valueIndex);
+ String nodeValue = m_values.get(valueIndex);
handler.addAttribute(uri, localName, nodeName, "CDATA", nodeValue);
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/AltCatalog.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/AltCatalog.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
}
/**
- * Returns the catalog attribute as an URI String.
+ * Returns the catalog attribute as a URI String.
* @return The value of the catalog attribute
*/
String getCatalogId() {
@@ -66,7 +66,7 @@
}
/**
- * Returns the catalog attribute as an URI.
+ * Returns the catalog attribute as a URI.
* @return The value of the catalog attribute
*/
URI getCatalogURI() {
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/BaseEntry.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/BaseEntry.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Objects;
+import static javax.xml.catalog.CatalogMessages.ERR_INVALID_ARGUMENT;
/**
* Represents a general Catalog entry.
@@ -210,13 +211,12 @@
* @param arg The name of the argument
* @param uri The URI to be verified
* @return The URI created from the specified uri
- * @throws IllegalArgumentException if the specified uri is null,
- * or an URL can not be created based on the specified base and uri
+ * @throws NullPointerException if the specified uri is null
+ * @throws IllegalArgumentException if a URL can not be created based on
+ * the specified base and uri
*/
URL verifyURI(String arg, URL base, String uri) {
- if (uri == null) {
- CatalogMessages.reportIAE(new Object[]{uri, arg}, null);
- }
+ CatalogMessages.reportNPEOnNull(arg, uri);
URL url = null;
uri = Normalizer.normalizeURI(uri);
@@ -228,32 +228,9 @@
url = new URL(uri);
}
} catch (MalformedURLException e) {
- CatalogMessages.reportIAE(new Object[]{uri, arg}, e);
+ CatalogMessages.reportIAE(ERR_INVALID_ARGUMENT,
+ new Object[]{uri, arg}, e);
}
return url;
}
-
- /**
- * Construct an absolute URI from a relative one, using the current base
- * URI.
- *
- * @param sysid The (possibly relative) system identifier
- * @return The system identifier made absolute with respect to the current
- * {@link #base}.
- */
- protected String makeAbsolute(String sysid) {
- URL local = null;
-
- sysid = Util.fixSlashes(sysid);
- /**
- * try { local = new URL(base, sysid); } catch (MalformedURLException e)
- * { catalogManager.debug.message(1, "Malformed URL on system
- * identifier", sysid); }
- */
- if (local != null) {
- return local.toString();
- } else {
- return sysid;
- }
- }
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -44,7 +44,7 @@
* <ul>
* <li>Locate the external resources with a public or system identifier;
* </li>
- * <li>Locate an alternate URI reference with an URI.
+ * <li>Locate an alternate URI reference with a URI.
* </li>
* </ul>
* <p>
@@ -84,7 +84,7 @@
*
* @param systemId the system identifier of the entity to be matched
*
- * @return an URI string if a mapping is found, or null otherwise
+ * @return a URI string if a mapping is found, or null otherwise
*/
public String matchSystem(String systemId);
@@ -108,7 +108,7 @@
*
* @param publicId the public identifier of the entity to be matched
* @see CatalogFeatures.Feature
- * @return an URI string if a mapping is found, or null otherwise
+ * @return a URI string if a mapping is found, or null otherwise
*/
public String matchPublic(String publicId);
@@ -134,7 +134,7 @@
*
* @param uri the URI reference of the entity to be matched
*
- * @return an URI string if a mapping is found, or null otherwise
+ * @return a URI string if a mapping is found, or null otherwise
*/
public String matchURI(String uri);
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -56,14 +56,14 @@
*
* <tr>
* <td><a name="FILES">FILES</a></td>
- * <td>A semicolon-delimited list of catalog files. Relative file paths are
- * considered relative to ${user.dir}.
+ * <td>A semicolon-delimited list of URIs to locate the catalog files.
+ * The URIs must be absolute and have a URL protocol handler for the URI scheme.
* </td>
* <td>javax.xml.catalog.files</td>
* <td>javax.xml.catalog.files</td>
* <td>javax.xml.catalog.files</td>
* <td>String</td>
- * <td>File paths</td>
+ * <td>URIs</td>
* <td>
* Reads the first catalog as the current catalog; Loads others if no match
* is found in the current catalog including delegate catalogs if any.
@@ -170,7 +170,7 @@
* Properties set through the Catalog API override those that may have been set
* by system properties and/or in {@code jaxp.properties}. In case of multiple
* interfaces, the latest in a procedure shall take preference. For
- * {@link Feature#FILES}, this means that the path(s) specified through the methods
+ * {@link Feature#FILES}, this means that the URI(s) specified through the methods
* of the {@link CatalogManager} will override any that may have been entered
* through the {@link Builder}.
*
@@ -188,7 +188,7 @@
* in the following sample code:
* <pre>{@code
CatalogFeatures f = CatalogFeatures.builder()
- .with(Feature.FILES, "catalog.xml")
+ .with(Feature.FILES, "file:///etc/xml/catalog")
.with(Feature.PREFER, "public")
.with(Feature.DEFER, "true")
.with(Feature.RESOLVE, "ignore")
@@ -202,14 +202,14 @@
* Schema Validation ({@link javax.xml.validation}), and XML Transformation
* ({@link javax.xml.transform}). The features described above can be set through JAXP
* factories or processors that define a setProperty or setAttribute interface.
- * For example, the following code snippet sets a path to a catalog file on a SAX
+ * For example, the following code snippet sets a URI to a catalog file on a SAX
* parser through the {@code javax.xml.catalog.files} property:
* <p>
* <pre>{@code
* SAXParserFactory spf = SAXParserFactory.newInstance();
* spf.setFeature(XMLConstants.USE_CATALOG, true); [1]
* SAXParser parser = spf.newSAXParser();
- * parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), "catalog.xml");
+ * parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), "file:///etc/xml/catalog");
* }</pre>
* <p>
* [1] Note that this statement is not required since the default value of
@@ -275,7 +275,7 @@
The following XInclude element:
<xi:include href="http://openjdk.java.net/xml/disclaimer.xml"/>
- can be resolved using an uri entry:
+ can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xml/disclaimer.xml" uri="file:///pathto/local/disclaimer.xml"/>
or
<uriSuffix uriSuffix="disclaimer.xml" uri="file:///pathto/local/disclaimer.xml"/>
@@ -291,7 +291,7 @@
<xsd:import namespace="http://openjdk.java.net/xsd/XSDImport_person"
schemaLocation="http://openjdk.java.net/xsd/XSDImport_person.xsd"/>
- can be resolved using an uri entry:
+ can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsd/XSDImport_person.xsd" uri="file:///pathto/local/XSDImport_person.xsd"/>
or
<uriSuffix uriSuffix="XSDImport_person.xsd" uri="file:///pathto/local/XSDImport_person.xsd"/>
@@ -308,7 +308,7 @@
The following include element:
<xsd:include schemaLocation="http://openjdk.java.net/xsd/XSDInclude_person.xsd"/>
- can be resolved using an uri entry:
+ can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsd/XSDInclude_person.xsd" uri="file:///pathto/local/XSDInclude_person.xsd"/>
or
<uriSuffix uriSuffix="XSDInclude_person.xsd" uri="file:///pathto/local/XSDInclude_person.xsd"/>
@@ -323,7 +323,7 @@
The following include element:
<xsl:include href="http://openjdk.java.net/xsl/include.xsl"/>
- can be resolved using an uri entry:
+ can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsl/include.xsl" uri="file:///pathto/local/include.xsl"/>
or
<uriSuffix uriSuffix="include.xsl" uri="file:///pathto/local/include.xsl"/>
@@ -338,7 +338,7 @@
The document in the following element:
<xsl:variable name="dummy" select="document('http://openjdk.java.net/xsl/list.xml')"/>
- can be resolved using an uri entry:
+ can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsl/list.xml" uri="file:///pathto/local/list.xml"/>
or
<uriSuffix uriSuffix="list.xml" uri="file:///pathto/local/list.xml"/>
@@ -559,7 +559,7 @@
values = new String[Feature.values().length];
states = new State[Feature.values().length];
for (Feature cf : Feature.values()) {
- setProperty(cf.ordinal(), State.DEFAULT, cf.defaultValue());
+ setProperty(cf, State.DEFAULT, cf.defaultValue());
}
//read system properties or jaxp.properties
readSystemProperties();
@@ -571,52 +571,27 @@
*/
private void setProperties(Builder builder) {
builder.values.entrySet().stream().forEach((entry) -> {
- setProperty(entry.getKey().ordinal(), State.APIPROPERTY, entry.getValue());
+ setProperty(entry.getKey(), State.APIPROPERTY, entry.getValue());
});
}
/**
- * Sets the value of a property by its index, updates only if it shall override.
+ * Sets the value of a property, updates only if it shall override.
*
* @param index the index of the property
* @param state the state of the property
* @param value the value of the property
* @throws IllegalArgumentException if the value is invalid
*/
- private void setProperty(int index, State state, String value) {
+ private void setProperty(Feature feature, State state, String value) {
+ int index = feature.ordinal();
if (value != null && value.length() != 0) {
- if (index == Feature.PREFER.ordinal()) {
- if (!value.equals(PREFER_SYSTEM) && !value.equals(PREFER_PUBLIC)) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.PREFER.name()}, null);
- }
- } else if (index == Feature.DEFER.ordinal()) {
- if (!value.equals(DEFER_TRUE) && !value.equals(DEFER_FALSE)) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.DEFER.name()}, null);
- }
- } else if (index == Feature.RESOLVE.ordinal()) {
- if (!value.equals(RESOLVE_STRICT) && !value.equals(RESOLVE_CONTINUE)
- && !value.equals(RESOLVE_IGNORE)) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.RESOLVE.name()}, null);
- }
- } else if (index == Feature.FILES.ordinal()) {
- try {
- String[] catalogFile = value.split(";[ ]*");
- for (String temp : catalogFile) {
- if (Util.verifyAndGetURI(temp, null) == null) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null);
- }
- }
- }catch (MalformedURLException | URISyntaxException | IllegalArgumentException ex) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, ex);
- }
+ if (state != State.APIPROPERTY) {
+ Util.validateFeatureInput(feature, value);
}
if (states[index] == null || state.compareTo(states[index]) >= 0) {
values[index] = value;
states[index] = state;
}
- } else {
- if (state == State.SYSTEMPROPERTY || state == State.JAXPDOTPROPERTIES) {
- CatalogMessages.reportIAE(new Object[]{value, Feature.values()[index].name()}, null);
- }
}
}
@@ -639,13 +614,13 @@
if (cf.hasSystemProperty()) {
String value = SecuritySupport.getSystemProperty(sysPropertyName);
if (value != null && !value.equals("")) {
- setProperty(cf.ordinal(), State.SYSTEMPROPERTY, value);
+ setProperty(cf, State.SYSTEMPROPERTY, value);
return true;
}
value = SecuritySupport.readJAXPProperty(sysPropertyName);
if (value != null && !value.equals("")) {
- setProperty(cf.ordinal(), State.JAXPDOTPROPERTIES, value);
+ setProperty(cf, State.JAXPDOTPROPERTIES, value);
return true;
}
}
@@ -685,9 +660,7 @@
* property
*/
public Builder with(Feature feature, String value) {
- if (value == null || value.length() == 0) {
- CatalogMessages.reportIAE(new Object[]{value, feature.name()}, null);
- }
+ Util.validateFeatureInput(feature, value);
values.put(feature, value);
return this;
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -75,7 +75,7 @@
/*
A list of catalog entry files from the input, excluding the current catalog.
- Paths in the List are normalized.
+ URIs in the List are verified during input validation or property retrieval.
*/
List<String> inputFiles;
@@ -86,43 +86,44 @@
SAXParser parser;
/**
- * Construct a Catalog with specified path.
+ * Construct a Catalog with specified URI.
*
- * @param file The path to a catalog file.
+ * @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
*/
- public CatalogImpl(CatalogFeatures f, String... file) throws CatalogException {
- this(null, f, file);
+ public CatalogImpl(CatalogFeatures f, URI... uris) throws CatalogException {
+ this(null, f, uris);
}
/**
- * Construct a Catalog with specified path.
+ * Construct a Catalog with specified URI.
*
* @param parent The parent catalog
- * @param file The path to a catalog file.
+ * @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
*/
- public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException {
+ public CatalogImpl(CatalogImpl parent, CatalogFeatures f, URI... uris) throws CatalogException {
super(CatalogEntryType.CATALOG, parent);
if (f == null) {
throw new NullPointerException(
formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"}));
}
- if (file.length > 0) {
- CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]);
- }
-
init(f);
//Path of catalog files
- String[] catalogFile = file;
- if (level == 0 && file.length == 0) {
+ String[] catalogFile = null;
+ if (level == 0 && uris.length == 0) {
String files = features.get(Feature.FILES);
if (files != null) {
- catalogFile = files.split(";[ ]*");
+ catalogFile = files.split(";");
+ }
+ } else {
+ catalogFile = new String[uris.length];
+ for (int i=0; i<uris.length; i++) {
+ catalogFile[i] = uris[i].toASCIIString();
}
}
@@ -134,10 +135,10 @@
int start = 0;
URI uri = null;
for (String temp : catalogFile) {
- uri = getSystemId(temp);
+ uri = URI.create(temp);
start++;
if (verifyCatalogFile(uri)) {
- systemId = uri.toASCIIString();
+ systemId = temp;
try {
baseURI = new URL(systemId);
} catch (MalformedURLException e) {
@@ -294,29 +295,6 @@
}
/**
- * Resolves the specified file path to an absolute systemId. If it is
- * relative, it shall be resolved using the base or user.dir property if
- * base is not specified.
- *
- * @param file The specified file path
- * @return The systemId of the file
- * @throws CatalogException if the specified file path can not be converted
- * to a system id
- */
- private URI getSystemId(String file) {
- URI temp = null;
-
- try {
- temp = Util.verifyAndGetURI(file, baseURI);
- } catch (MalformedURLException | URISyntaxException | IllegalArgumentException e) {
- CatalogMessages.reportRunTimeError(CatalogMessages.ERR_INVALID_PATH,
- new Object[]{file}, e);
- }
-
- return temp;
- }
-
- /**
* Returns a SAXParser instance
* @return a SAXParser instance
* @throws CatalogException if constructing a SAXParser failed
@@ -394,7 +372,7 @@
//Check the input list
if (c == null && inputFiles != null) {
while (c == null && inputFilesIndex < inputFiles.size()) {
- c = getCatalog(getSystemId(inputFiles.get(inputFilesIndex++)));
+ c = getCatalog(URI.create(inputFiles.get(inputFilesIndex++)));
}
}
@@ -436,8 +414,8 @@
//loads catalogs from the input list
if (inputFiles != null) {
- inputFiles.stream().forEach((file) -> {
- getCatalog(getSystemId(file));
+ inputFiles.stream().forEach((uri) -> {
+ getCatalog(URI.create(uri));
});
}
}
@@ -454,12 +432,11 @@
}
CatalogImpl c = null;
- String path = uri.toASCIIString();
if (verifyCatalogFile(uri)) {
- c = getLoadedCatalog(path);
+ c = getLoadedCatalog(uri.toASCIIString());
if (c == null) {
- c = new CatalogImpl(this, features, path);
+ c = new CatalogImpl(this, features, uri);
c.load();
}
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
*/
package javax.xml.catalog;
+import java.net.URI;
/**
* The Catalog Manager manages the creation of XML Catalogs and Catalog Resolvers.
@@ -39,30 +40,36 @@
/**
* Creates a {@code Catalog} object using the specified feature settings and
- * path to one or more catalog files.
+ * uri(s) to one or more catalog files.
* <p>
- * If {@code paths} is empty, system property {@code javax.xml.catalog.files}
- * will be read to locate the initial list of catalog files.
+ * If {@code uris} is empty, system property {@code javax.xml.catalog.files},
+ * as defined in {@link CatalogFeatures}, will be read to locate the initial
+ * list of catalog files.
* <p>
- * If more than one catalog files are specified through the paths argument or
+ * If multiple catalog files are specified through the {@code uris} argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
* <p>
* As specified in
* <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
- * XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
- * No error will be reported. In case all entries are invalid, the resolver
- * will return as no mapping is found.
+ * XML Catalogs, OASIS Standard V1.1</a>, if a catalog entry is invalid, it
+ * is ignored. In case all entries are invalid, the resulting Catalog object
+ * will contain no Catalog elements. Any matching operation using the Catalog
+ * will return null.
*
* @param features the catalog features
- * @param paths path(s) to one or more catalogs.
+ * @param uris uri(s) to one or more catalogs.
*
* @return an instance of a {@code Catalog}
+ * @throws IllegalArgumentException if either the URIs are not absolute
+ * or do not have a URL protocol handler for the URI scheme
* @throws CatalogException If an error occurs while parsing the catalog
+ * @throws SecurityException if access to the resource is denied by the security manager
*/
- public static Catalog catalog(CatalogFeatures features, String... paths) {
- CatalogImpl catalog = new CatalogImpl(features, paths);
+ public static Catalog catalog(CatalogFeatures features, URI... uris) {
+ Util.validateUrisSyntax(uris);
+ CatalogImpl catalog = new CatalogImpl(features, uris);
catalog.load();
return catalog;
}
@@ -80,30 +87,36 @@
/**
* Creates an instance of a {@code CatalogResolver} using the specified feature
- * settings and path to one or more catalog files.
+ * settings and uri(s) to one or more catalog files.
* <p>
- * If {@code paths} is empty, system property {@code javax.xml.catalog.files}
- * will be read to locate the initial list of catalog files.
+ * If {@code uris} is empty, system property {@code javax.xml.catalog.files},
+ * as defined in {@link CatalogFeatures}, will be read to locate the initial
+ * list of catalog files.
* <p>
- * If more than one catalog files are specified through the paths argument or
+ * If multiple catalog files are specified through the {@code uris} argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
* <p>
* As specified in
* <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
- * XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
- * No error will be reported. In case all entries are invalid, the resolver
- * will return as no mapping is found.
+ * XML Catalogs, OASIS Standard V1.1</a>, if a catalog entry is invalid, it
+ * is ignored. In case all entries are invalid, the resulting CatalogResolver
+ * object will contain no valid catalog. Any resolution operation using the
+ * resolver therefore will return as no mapping is found. See {@link CatalogResolver}
+ * for the behavior when no mapping is found.
*
* @param features the catalog features
- * @param paths the path(s) to one or more catalogs
+ * @param uris the uri(s) to one or more catalogs
*
* @return an instance of a {@code CatalogResolver}
+ * @throws IllegalArgumentException if either the URIs are not absolute
+ * or do not have a URL protocol handler for the URI scheme
* @throws CatalogException If an error occurs while parsing the catalog
+ * @throws SecurityException if access to the resource is denied by the security manager
*/
- public static CatalogResolver catalogResolver(CatalogFeatures features, String... paths) {
- Catalog catalog = catalog(features, paths);
+ public static CatalogResolver catalogResolver(CatalogFeatures features, URI... uris) {
+ Catalog catalog = catalog(features, uris);
return new CatalogResolverImpl(catalog);
}
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,11 @@
*/
package javax.xml.catalog;
-import jdk.xml.internal.SecuritySupport;
+import java.net.URI;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import jdk.xml.internal.SecuritySupport;
/**
* Catalog Error messages
@@ -38,6 +39,8 @@
public static final String ERR_INVALID_CATALOG = "InvalidCatalog";
public static final String ERR_INVALID_ENTRY_TYPE = "InvalidEntryType";
+ public static final String ERR_URI_NOTABSOLUTE = "UriNotAbsolute";
+ public static final String ERR_URI_NOTVALIDURL = "UriNotValidUrl";
public static final String ERR_INVALID_ARGUMENT = "InvalidArgument";
public static final String ERR_NULL_ARGUMENT = "NullArgument";
public static final String ERR_CIRCULAR_REFERENCE = "CircularReference";
@@ -120,7 +123,7 @@
* @param name the name of the argument
* @param value the value of the argument
*/
- static void reportNPEOnNull(String name, String value) {
+ static void reportNPEOnNull(String name, Object value) {
if (value == null) {
throw new NullPointerException(
formatMessage(ERR_NULL_ARGUMENT, new Object[]{name}));
@@ -132,9 +135,9 @@
* @param arguments the arguments for formating the error message
* @param cause the cause if any
*/
- static void reportIAE(Object[] arguments, Throwable cause) {
+ static void reportIAE(String key, Object[] arguments, Throwable cause) {
throw new IllegalArgumentException(
- formatMessage(ERR_INVALID_ARGUMENT, arguments), cause);
+ formatMessage(key, arguments), cause);
}
/**
@@ -174,7 +177,7 @@
/**
* Returns sanitized URI.
- * @param uri an URI to be sanitized
+ * @param uri a URI to be sanitized
*/
static String sanitize(String uri) {
if (uri == null) {
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Tue Jan 24 00:30:23 2017 +0100
@@ -31,6 +31,8 @@
CircularReference = Circular reference is not allowed: ''{0}''.
#errors
+UriNotAbsolute = The specified URI ''{0}'' is not absolute.
+UriNotValidUrl = The specified URI ''{0}'' is not a valid URL.
InvalidArgument = The specified argument ''{0}'' (case sensitive) for ''{1}'' is not valid.
NullArgument = The argument ''{0}'' can not be null.
InvalidPath = The path ''{0}'' is invalid.
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,6 @@
package javax.xml.catalog;
import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import javax.xml.catalog.BaseEntry.CatalogEntryType;
import javax.xml.parsers.SAXParser;
import javax.xml.transform.Source;
@@ -94,25 +90,6 @@
this.parser = parser;
}
- /**
- * Returns when the specified path is valid.
- * @param path a path
- * @return true if the path is valid, false otherwise
- */
- boolean isValidPath(String path) {
- boolean valid = true;
- try {
- Path p = Paths.get(new URI(path));
- if (!p.toFile().exists()) {
- valid = false;
- }
- } catch (URISyntaxException ex) {
- valid = false;
- }
-
- return valid;
- }
-
@Override
public void startElement(String namespaceURI,
String localName,
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -47,7 +47,7 @@
* {@link javax.xml.stream.XMLResolver} and {@link org.w3c.dom.ls.LSResourceResolver}
* however, make no such distinction.
* In consistent with the existing Java API, this CatalogResolver recognizes a
- * system identifier as an URI and will search both {@code system} and {@code uri}
+ * system identifier as a URI and will search both {@code system} and {@code uri}
* entries in a catalog in order to find a matching entry.
* <p>
* The search is started in the current catalog. If a match is found,
@@ -137,9 +137,9 @@
* with the specified {@code href} attribute. The {@code href} attribute will
* be used literally, with no attempt to be made absolute to the {@code base}.
* <p>
- * If the value is an URN, the {@code href} attribute is recognized as a
+ * If the value is a URN, the {@code href} attribute is recognized as a
* {@code publicId}, and used to search {@code public} entries.
- * If the value is an URI, it is taken as a {@code systemId}, and used to
+ * If the value is a URI, it is taken as a {@code systemId}, and used to
* search both {@code system} and {@code uri} entries.
*
*
@@ -219,7 +219,7 @@
* @param publicId the public identifier of the external entity being
* referenced, or {@code null} if no public identifier was
* supplied or if the resource is not an entity.
- * @param systemId the system identifier, an URI reference of the
+ * @param systemId the system identifier, a URI reference of the
* external resource being referenced
* @param baseUri the absolute base URI, not used by the CatalogResolver
*
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -73,7 +73,7 @@
systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
- //check whether systemId is an urn
+ //check whether systemId is a urn
if (systemId != null && systemId.startsWith(Util.URN)) {
systemId = Normalizer.decodeURN(systemId);
if (publicId != null && !publicId.equals(systemId)) {
@@ -123,7 +123,7 @@
return null;
}
- //check whether uri is an urn
+ //check whether uri is a urn
if (uri != null && uri.startsWith(Util.URN)) {
String publicId = Normalizer.decodeURN(uri);
if (publicId != null) {
@@ -131,7 +131,7 @@
}
}
- //if no match with a public id, continue search for an URI
+ //if no match with a public id, continue search for a URI
if (result == null) {
//remove fragment if any.
int hashPos = uri.indexOf("#");
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,6 @@
package javax.xml.catalog;
import java.net.URI;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -217,7 +215,7 @@
* @param systemId The system identifier of the external entity being
* referenced.
*
- * @return An URI string if a mapping is found, or null otherwise.
+ * @return a URI string if a mapping is found, or null otherwise.
*/
public String matchSystem(String systemId) {
systemEntrySearched = true;
@@ -285,7 +283,7 @@
* @param publicId The public identifier of the external entity being
* referenced.
*
- * @return An URI string if a mapping is found, or null otherwise.
+ * @return a URI string if a mapping is found, or null otherwise.
*/
public String matchPublic(String publicId) {
/*
@@ -329,7 +327,7 @@
*
* @param uri The URI reference of a resource.
*
- * @return An URI string if a mapping is found, or null otherwise.
+ * @return a URI string if a mapping is found, or null otherwise.
*/
public String matchURI(String uri) {
String match = null;
@@ -455,7 +453,7 @@
delegateCatalog = getLoadedCatalog(catalogId);
if (delegateCatalog == null) {
if (verifyCatalogFile(catalogURI)) {
- delegateCatalog = new CatalogImpl(catalog, features, catalogId);
+ delegateCatalog = new CatalogImpl(catalog, features, catalogURI);
delegateCatalog.load();
delegateCatalogs.put(catalogId, delegateCatalog);
}
@@ -504,7 +502,8 @@
}
//Ignore it if it doesn't exist
- if (!Files.exists(Paths.get(catalogURI))) {
+ if (Util.isFileUri(catalogURI) &&
+ !Util.isFileUriExist(catalogURI, false)) {
return false;
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/UriEntry.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/UriEntry.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
import java.net.URL;
/**
- * Represents an uriEntry entry.
+ * Represents a uri entry.
*
* @since 9
*/
@@ -36,7 +36,7 @@
URL uri;
/**
- * Construct a group entry.
+ * Construct a uri entry.
* @param name The name attribute.
* @param uri The uri attribute.
*/
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,20 @@
package javax.xml.catalog;
import java.io.File;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.Iterator;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import static javax.xml.catalog.CatalogFeatures.DEFER_FALSE;
+import static javax.xml.catalog.CatalogFeatures.DEFER_TRUE;
+import javax.xml.catalog.CatalogFeatures.Feature;
+import static javax.xml.catalog.CatalogFeatures.PREFER_PUBLIC;
+import static javax.xml.catalog.CatalogFeatures.PREFER_SYSTEM;
+import static javax.xml.catalog.CatalogFeatures.RESOLVE_CONTINUE;
+import static javax.xml.catalog.CatalogFeatures.RESOLVE_IGNORE;
+import static javax.xml.catalog.CatalogFeatures.RESOLVE_STRICT;
import jdk.xml.internal.SecuritySupport;
/**
@@ -39,22 +46,25 @@
* @since 9
*/
class Util {
+
final static String URN = "urn:publicid:";
final static String PUBLICID_PREFIX = "-//";
final static String PUBLICID_PREFIX_ALT = "+//";
+ final static String SCHEME_FILE = "file";
+ final static String SCHEME_JAR = "jar";
+ final static String SCHEME_JARFILE = "jar:file:";
/**
* Finds an entry in the catalog that matches with the publicId or systemId.
*
- * The resolution follows the following rules determined by the prefer setting:
+ * The resolution follows the following rules determined by the prefer
+ * setting:
*
- * prefer "system": attempts to resolve with a system entry;
- * attempts to resolve with a public entry when only
- * publicId is specified.
+ * prefer "system": attempts to resolve with a system entry; attempts to
+ * resolve with a public entry when only publicId is specified.
*
- * prefer "public": attempts to resolve with a system entry;
- * attempts to resolve with a public entry if no matching
- * system entry is found.
+ * prefer "public": attempts to resolve with a system entry; attempts to
+ * resolve with a public entry if no matching system entry is found.
*
* If no match is found, continue searching uri entries
*
@@ -70,9 +80,9 @@
catalog.reset();
if (systemId != null) {
/*
- If a system identifier is specified, it is used no matter how
- prefer is set.
- */
+ If a system identifier is specified, it is used no matter how
+ prefer is set.
+ */
resolvedSystemId = catalog.matchSystem(systemId);
}
@@ -91,7 +101,7 @@
if (resolvedSystemId == null) {
Iterator<Catalog> iter = catalog.catalogs().iterator();
while (iter.hasNext()) {
- resolvedSystemId = resolve((CatalogImpl)iter.next(), publicId, systemId);
+ resolvedSystemId = resolve((CatalogImpl) iter.next(), publicId, systemId);
if (resolvedSystemId != null) {
break;
}
@@ -102,73 +112,112 @@
return resolvedSystemId;
}
+ static void validateUrisSyntax(URI... uris) {
+ for (URI uri : uris) {
+ validateUriSyntax(uri);
+ }
+ }
+
+ static void validateUrisSyntax(String... uris) {
+ for (String uri : uris) {
+ validateUriSyntax(URI.create(uri));
+ }
+ }
+
/**
- * Resolves the specified file path to an absolute systemId. If it is
- * relative, it shall be resolved using the base or user.dir property if
- * base is not specified.
+ * Validate that the URI must be absolute and a valid URL.
*
- * @param file The specified file path
- * @param baseURI the base URI
- * @return The URI
- * @throws CatalogException if the specified file path can not be converted
- * to a system id
+ * Note that this method does not verify the existence of the resource. The
+ * Catalog standard requires that such resources be ignored.
+ *
+ * @param uri
+ * @throws IllegalArgumentException if the uri is not absolute and a valid
+ * URL
*/
- static URI verifyAndGetURI(String file, URL baseURI)
- throws MalformedURLException, URISyntaxException, IllegalArgumentException {
- URL filepath;
- URI temp;
- if (file != null && file.length() > 0) {
- File f = new File(file);
+ static void validateUriSyntax(URI uri) {
+ CatalogMessages.reportNPEOnNull("URI input", uri);
+
+ if (!uri.isAbsolute()) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTABSOLUTE,
+ new Object[]{uri}, null);
+ }
- if (baseURI != null && !f.isAbsolute()) {
- filepath = new URL(baseURI, fixSlashes(file));
- temp = filepath.toURI();
- } else {
- temp = resolveURI(file);
- }
- //Paths.get may throw IllegalArgumentException
- Path path = Paths.get(temp);
- if (path.toFile().isFile()) {
- return temp;
+ try {
+ // check if the scheme was valid
+ uri.toURL();
+ } catch (MalformedURLException ex) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTVALIDURL,
+ new Object[]{uri}, null);
+ }
+
+ // verify the resource exists where possible
+ if (isFileUri(uri)) {
+ if (!isFileUriExist(uri, false)) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTVALIDURL,
+ new Object[]{uri}, null);
}
}
- return null;
}
/**
- * Resolves the specified uri. If the uri is relative, makes it absolute by
- * the user.dir directory.
+ * Checks whether the URI is a file URI, including JAR file.
*
- * @param uri The specified URI.
- * @return The resolved URI
+ * @param uri the specified URI.
+ * @return true if it is a file or JAR file URI, false otherwise
*/
- static URI resolveURI(String uri) throws MalformedURLException {
- if (uri == null) {
- uri = "";
+ static boolean isFileUri(URI uri) {
+ if (SCHEME_FILE.equals(uri.getScheme())
+ || SCHEME_JAR.equals(uri.getScheme())) {
+ return true;
}
-
- URI temp = null;
- try {
- URL url = new URL(uri);
- temp = url.toURI();
- } catch (MalformedURLException | URISyntaxException mue) {
- File file = new File(uri);
- temp = file.toURI();
- }
-
- return temp;
+ return false;
}
/**
- * Replace backslashes with forward slashes. (URLs always use forward
- * slashes.)
+ * Verifies whether the file resource exists.
*
- * @param sysid The input system identifier.
- * @return The same system identifier with backslashes turned into forward
- * slashes.
+ * @param uri the URI to locate the resource
+ * @param openJarFile a flag to indicate whether a JAR file should be
+ * opened. This operation may be expensive.
+ * @return true if the resource exists, false otherwise.
*/
- static String fixSlashes(String sysid) {
- return sysid.replace('\\', '/');
+ static boolean isFileUriExist(URI uri, boolean openJarFile) {
+ if (uri != null && uri.isAbsolute()) {
+ if (null != uri.getScheme()) {
+ switch (uri.getScheme()) {
+ case SCHEME_FILE:
+ String path = uri.getPath();
+ File f1 = new File(path);
+ if (f1.isFile()) {
+ return true;
+ }
+ break;
+ case SCHEME_JAR:
+ String tempUri = uri.toString();
+ int pos = tempUri.indexOf("!");
+ if (pos < 0) {
+ return false;
+ }
+ if (openJarFile) {
+ String jarFile = tempUri.substring(SCHEME_JARFILE.length(), pos);
+ String entryName = tempUri.substring(pos + 2);
+ try {
+ JarFile jf = new JarFile(jarFile);
+ JarEntry je = jf.getJarEntry(entryName);
+ if (je != null) {
+ return true;
+ }
+ } catch (IOException ex) {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ return false;
}
/**
@@ -187,11 +236,12 @@
}
/**
- * Checks whether the specified string is null or empty, returns the original
- * string with leading and trailing spaces removed if not.
+ * Checks whether the specified string is null or empty, returns the
+ * original string with leading and trailing spaces removed if not.
+ *
* @param test the string to be tested
- * @return the original string with leading and trailing spaces removed,
- * or null if it is null or empty
+ * @return the original string with leading and trailing spaces removed, or
+ * null if it is null or empty
*
*/
static String getNotNullOrEmpty(String test) {
@@ -206,4 +256,39 @@
}
}
}
+
+ /**
+ * Validates the input for features.
+ *
+ * @param f the feature
+ * @param value the value
+ * @throws IllegalArgumentException if the value is invalid for the feature
+ */
+ static void validateFeatureInput(Feature f, String value) {
+ CatalogMessages.reportNPEOnNull(f.name(), value);
+ if (value.length() == 0) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
+ new Object[]{value, f.name()}, null);
+ }
+
+ if (f == Feature.PREFER) {
+ if (!value.equals(PREFER_SYSTEM) && !value.equals(PREFER_PUBLIC)) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
+ new Object[]{value, Feature.PREFER.name()}, null);
+ }
+ } else if (f == Feature.DEFER) {
+ if (!value.equals(DEFER_TRUE) && !value.equals(DEFER_FALSE)) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
+ new Object[]{value, Feature.DEFER.name()}, null);
+ }
+ } else if (f == Feature.RESOLVE) {
+ if (!value.equals(RESOLVE_STRICT) && !value.equals(RESOLVE_CONTINUE)
+ && !value.equals(RESOLVE_IGNORE)) {
+ CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
+ new Object[]{value, Feature.RESOLVE.name()}, null);
+ }
+ } else if (f == Feature.FILES) {
+ Util.validateUrisSyntax(value.split(";"));
+ }
+ }
}
--- a/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -81,7 +81,7 @@
@Test
public void specifyCatalogViaSysProps() {
setSystemProperty(FEATURE_FILES,
- getCatalogPath("specifyCatalog-sysProps.xml"));
+ getCatalogPath("specifyCatalog-sysProps.xml").toASCIIString());
checkResolutionOnEntityResolver(catalogResolver((String[]) null),
"http://local/base/dtd/docSysPropsSys.dtd");
@@ -107,6 +107,6 @@
}
private static CatalogFeatures createFeature(String catalogName) {
- return builder().with(FILES, getCatalogPath(catalogName)).build();
+ return builder().with(FILES, getCatalogPath(catalogName).toASCIIString()).build();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/dummy.xml Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,1 @@
+<dummy />
--- a/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,16 @@
import java.io.File;
import java.io.IOException;
+import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver;
-
import jaxp.library.JAXPTestUtilities;
/*
@@ -115,20 +114,20 @@
}
// Gets the paths of the specified catalogs.
- private static String[] getCatalogPaths(String... catalogNames) {
+ private static URI[] getCatalogPaths(String... catalogNames) {
return catalogNames == null
? null
: Stream.of(catalogNames).map(
catalogName -> getCatalogPath(catalogName)).collect(
- Collectors.toList()).toArray(new String[0]);
+ Collectors.toList()).toArray(new URI[0]);
}
// Gets the paths of the specified catalogs.
- static String getCatalogPath(String catalogName) {
+ static URI getCatalogPath(String catalogName) {
return catalogName == null
? null
- : JAXPTestUtilities.getPathByClassName(CatalogTestUtils.class, "catalogFiles")
- + catalogName;
+ : Paths.get(JAXPTestUtilities.getPathByClassName(CatalogTestUtils.class, "catalogFiles")
+ + catalogName).toUri();
}
/* ********** jaxp.properties ********** */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JarUtils.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jaxp.library;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * This class consists exclusively of static utility methods that are useful
+ * for creating and manipulating JAR files.
+ */
+
+public final class JarUtils {
+ private JarUtils() { }
+
+ /**
+ * Creates a JAR file.
+ *
+ * Equivalent to {@code jar cfm <jarfile> <manifest> -C <dir> file...}
+ *
+ * The input files are resolved against the given directory. Any input
+ * files that are directories are processed recursively.
+ */
+ public static void createJarFile(Path jarfile, Manifest man, Path dir, Path... file)
+ throws IOException
+ {
+ // create the target directory
+ Path parent = jarfile.getParent();
+ if (parent != null)
+ Files.createDirectories(parent);
+
+ List<Path> entries = new ArrayList<>();
+ for (Path entry : file) {
+ Files.find(dir.resolve(entry), Integer.MAX_VALUE,
+ (p, attrs) -> attrs.isRegularFile())
+ .map(e -> dir.relativize(e))
+ .forEach(entries::add);
+ }
+
+ try (OutputStream out = Files.newOutputStream(jarfile);
+ JarOutputStream jos = new JarOutputStream(out))
+ {
+ if (man != null) {
+ JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
+ jos.putNextEntry(je);
+ man.write(jos);
+ jos.closeEntry();
+ }
+
+ for (Path entry : entries) {
+ String name = toJarEntryName(entry);
+ jos.putNextEntry(new JarEntry(name));
+ Files.copy(dir.resolve(entry), jos);
+ jos.closeEntry();
+ }
+ }
+ }
+
+ /**
+ * Creates a JAR file.
+ *
+ * Equivalent to {@code jar cf <jarfile> -C <dir> file...}
+ *
+ * The input files are resolved against the given directory. Any input
+ * files that are directories are processed recursively.
+ */
+ public static void createJarFile(Path jarfile, Path dir, Path... file)
+ throws IOException
+ {
+ createJarFile(jarfile, null, dir, file);
+ }
+
+ /**
+ * Creates a JAR file.
+ *
+ * Equivalent to {@code jar cf <jarfile> -C <dir> file...}
+ *
+ * The input files are resolved against the given directory. Any input
+ * files that are directories are processed recursively.
+ */
+ public static void createJarFile(Path jarfile, Path dir, String... input)
+ throws IOException
+ {
+ Path[] paths = Stream.of(input).map(Paths::get).toArray(Path[]::new);
+ createJarFile(jarfile, dir, paths);
+ }
+
+ /**
+ * Creates a JAR file from the contents of a directory.
+ *
+ * Equivalent to {@code jar cf <jarfile> -C <dir> .}
+ */
+ public static void createJarFile(Path jarfile, Path dir) throws IOException {
+ createJarFile(jarfile, dir, Paths.get("."));
+ }
+
+ /**
+ * Map a file path to the equivalent name in a JAR file
+ */
+ private static String toJarEntryName(Path file) {
+ Path normalized = file.normalize();
+ return normalized.subpath(0, normalized.getNameCount()) // drop root
+ .toString()
+ .replace(File.separatorChar, '/');
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/SimpleHttpServer.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jaxp.library;
+
+import com.sun.net.httpserver.Headers;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * A simple HTTP Server
+ */
+public class SimpleHttpServer {
+ HttpServer _httpserver;
+ ExecutorService _executor;
+
+ String _address;
+
+ String _context, _docroot;
+ int _port;
+
+ public SimpleHttpServer(String context, String docroot) {
+ //let the system pick up an ephemeral port in a bind operation
+ this(0, context, docroot);
+ }
+
+ public SimpleHttpServer(int port, String context, String docroot) {
+ _port = port;
+ _context = context;
+ _docroot = docroot;
+ }
+
+ public void start() {
+ MyHttpHandler handler = new MyHttpHandler(_docroot);
+ InetSocketAddress addr = new InetSocketAddress(_port);
+ try {
+ _httpserver = HttpServer.create(addr, 0);
+ } catch (IOException ex) {
+ throw new RuntimeException("cannot create httpserver", ex);
+ }
+
+ //TestHandler is mapped to /test
+ HttpContext ctx = _httpserver.createContext(_context, handler);
+
+ _executor = Executors.newCachedThreadPool();
+ _httpserver.setExecutor(_executor);
+ _httpserver.start();
+
+ _address = "http://localhost:" + _httpserver.getAddress().getPort();
+ }
+
+ public void stop() {
+ _httpserver.stop(2);
+ _executor.shutdown();
+ }
+
+ public String getAddress() {
+ return _address;
+ }
+
+ static class MyHttpHandler implements HttpHandler {
+
+ String _docroot;
+
+ public MyHttpHandler(String docroot) {
+ _docroot = docroot;
+ }
+
+ public void handle(HttpExchange t)
+ throws IOException {
+ InputStream is = t.getRequestBody();
+ Headers map = t.getRequestHeaders();
+ Headers rmap = t.getResponseHeaders();
+ OutputStream os = t.getResponseBody();
+ URI uri = t.getRequestURI();
+ String path = uri.getPath();
+
+
+ while (is.read() != -1) ;
+ is.close();
+
+ File f = new File(_docroot, path);
+ if (!f.exists()) {
+ notfound(t, path);
+ return;
+ }
+
+ String method = t.getRequestMethod();
+ if (method.equals("HEAD")) {
+ rmap.set("Content-Length", Long.toString(f.length()));
+ t.sendResponseHeaders(200, -1);
+ t.close();
+ } else if (!method.equals("GET")) {
+ t.sendResponseHeaders(405, -1);
+ t.close();
+ return;
+ }
+
+ if (path.endsWith(".html") || path.endsWith(".htm")) {
+ rmap.set("Content-Type", "text/html");
+ } else {
+ rmap.set("Content-Type", "text/plain");
+ }
+
+ t.sendResponseHeaders (200, f.length());
+
+ FileInputStream fis = new FileInputStream(f);
+ int count = 0;
+ try {
+ byte[] buf = new byte[16 * 1024];
+ int len;
+ while ((len = fis.read(buf)) != -1) {
+ os.write(buf, 0, len);
+ count += len;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ fis.close();
+ os.close();
+ }
+
+ void moved(HttpExchange t) throws IOException {
+ Headers req = t.getRequestHeaders();
+ Headers map = t.getResponseHeaders();
+ URI uri = t.getRequestURI();
+ String host = req.getFirst("Host");
+ String location = "http://" + host + uri.getPath() + "/";
+ map.set("Content-Type", "text/html");
+ map.set("Location", location);
+ t.sendResponseHeaders(301, -1);
+ t.close();
+ }
+
+ void notfound(HttpExchange t, String p) throws IOException {
+ t.getResponseHeaders().set("Content-Type", "text/html");
+ t.sendResponseHeaders(404, 0);
+ OutputStream os = t.getResponseBody();
+ String s = "<h2>File not found</h2>";
+ s = s + p + "<p>";
+ os.write(s.getBytes());
+ os.close();
+ t.close();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogAccessTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package catalog;
+
+import java.net.URI;
+import javax.xml.catalog.CatalogFeatures;
+import javax.xml.catalog.CatalogManager;
+import javax.xml.catalog.CatalogResolver;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.xml.sax.InputSource;
+import static jaxp.library.JAXPTestUtilities.tryRunWithAllPerm;
+
+/*
+ * @test
+ * @bug 8171243
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true catalog.CatalogAccessTest
+ * @summary the Catalog API grants no privilege to external resources. This test
+ * verifies that SecurityException will be thrown if access to resources is denied
+ * by the security manager.
+ */
+@Listeners({jaxp.library.BasePolicy.class})
+public class CatalogAccessTest {
+ static final CatalogFeatures FEATURES = CatalogFeatures.builder().
+ with(CatalogFeatures.Feature.PREFER, "system").build();
+
+ /*
+ * Verifies that the SecurityException is thrown if access to the resource is
+ * denied by the security manager.
+ */
+ @Test(dataProvider = "accessTest", expectedExceptions = SecurityException.class)
+ public void testSecurity(String cfile, String sysId, String pubId) throws Exception {
+ CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, URI.create(cfile));
+ InputSource is = cr.resolveEntity(pubId, sysId);
+ Assert.fail("Failed to throw SecurityException");
+ }
+
+ /*
+ DataProvider: used for SecurityException testing
+ Data columns:
+ catalog uri, systemId, publicId
+ */
+ @DataProvider(name = "accessTest")
+ Object[][] getDataForAccessTest() throws Exception {
+ String systemId = "http://www.sys00test.com/rewrite.dtd";
+ String publicId = "PUB-404";
+ String urlFile = tryRunWithAllPerm(() ->
+ getClass().getResource("rewriteSystem_id.xml").toExternalForm());
+ return new Object[][]{
+ {urlFile, systemId, publicId}
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogFileInputTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package catalog;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import static java.nio.file.StandardOpenOption.APPEND;
+import static java.nio.file.StandardOpenOption.CREATE;
+import javax.xml.catalog.Catalog;
+import javax.xml.catalog.CatalogException;
+import javax.xml.catalog.CatalogFeatures;
+import javax.xml.catalog.CatalogManager;
+import javax.xml.catalog.CatalogResolver;
+import static jaxp.library.JAXPTestUtilities.getSystemProperty;
+import jaxp.library.JarUtils;
+import jaxp.library.SimpleHttpServer;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.xml.sax.InputSource;
+
+/*
+ * @test
+ * @bug 8151154 8171243
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm catalog.CatalogFileInputTest
+ * @summary Verifies that the Catalog API accepts valid URIs only;
+ Verifies that the CatalogFeatures' builder throws
+ * IllegalArgumentException on invalid file inputs.
+ * This test was splitted from CatalogTest.java due to
+ * JDK-8168968, it has to only run without SecurityManager
+ * because an ACE will be thrown for invalid path.
+ */
+@Listeners({jaxp.library.FilePolicy.class, jaxp.library.NetAccessPolicy.class})
+public class CatalogFileInputTest extends CatalogSupportBase {
+
+ static final CatalogFeatures FEATURES = CatalogFeatures.builder().
+ with(CatalogFeatures.Feature.PREFER, "system").build();
+ static String USER_DIR = getSystemProperty("user.dir");
+ static String CLS_DIR = getSystemProperty("test.classes");
+ static String SRC_DIR = System.getProperty("test.src");
+ static String JAR_CONTENT = "META-INF";
+ final static String SCHEME_JARFILE = "jar:";
+ static final String REMOTE_FILE_LOCATION = "/jar/META-INF";
+ static final String DOCROOT = SRC_DIR;
+ static final String TESTCONTEXT = REMOTE_FILE_LOCATION; //mapped to local file path
+ SimpleHttpServer _httpserver;
+ String _remoteFilePath;
+
+ /*
+ * Initializing fields
+ */
+ @BeforeClass
+ public void setUpClass() throws Exception {
+ super.setUp();
+
+ // set up HttpServer
+ _httpserver = new SimpleHttpServer(TESTCONTEXT, DOCROOT);
+ _httpserver.start();
+ _remoteFilePath = _httpserver.getAddress() + REMOTE_FILE_LOCATION;
+
+ }
+
+ @AfterClass
+ protected void tearDown() throws Exception {
+ if (_httpserver != null) {
+ _httpserver.stop();
+ }
+ }
+
+ /*
+ * Verifies that the Catalog can be created with file system paths including JAR
+ * and http URL, and used to resolve a systemId as expected.
+ */
+ @Test(dataProvider = "acceptedURI")
+ public void testMatch(String uri, String sysId, String pubId,
+ String expectedId, String msg) throws Exception {
+ CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, URI.create(uri));
+ InputSource is = cr.resolveEntity(pubId, sysId);
+ Assert.assertNotNull(is, msg);
+ Assert.assertEquals(expectedId, is.getSystemId(), msg);
+ }
+
+ @Test(dataProvider = "invalidCatalog")
+ public void testEmptyCatalog(String uri, String publicId, String msg) {
+ Catalog c = CatalogManager.catalog(FEATURES, uri != null? URI.create(uri) : null);
+ Assert.assertNull(c.matchSystem(publicId), msg);
+ }
+
+ @Test(dataProvider = "invalidCatalog", expectedExceptions = CatalogException.class)
+ public void testCatalogResolverWEmptyCatalog(String uri, String publicId, String msg) {
+ CatalogResolver cr = CatalogManager.catalogResolver(
+ CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "strict").build(),
+ uri != null? URI.create(uri) : null);
+ InputSource is = cr.resolveEntity(publicId, "");
+ }
+
+ @Test(dataProvider = "invalidCatalog")
+ public void testCatalogResolverWEmptyCatalog1(String uri, String publicId, String msg) {
+ CatalogResolver cr = CatalogManager.catalogResolver(
+ CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "continue").build(),
+ uri != null? URI.create(uri) : null);
+ Assert.assertNull(cr.resolveEntity(publicId, ""), msg);
+ }
+
+ @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
+ public void testFileInput(String file) {
+ CatalogFeatures features = CatalogFeatures.builder()
+ .with(CatalogFeatures.Feature.FILES, file)
+ .build();
+ }
+
+ @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
+ public void testInvalidUri(String file) {
+ CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, file != null? URI.create(file) : null);
+ }
+
+ @Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
+ public void testInvalidUri1(String file) {
+ Catalog c = CatalogManager.catalog(FEATURES, file != null? URI.create(file) : null);
+ System.err.println("Catalog =" + c);
+ }
+
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullFileInput() {
+ CatalogFeatures features = CatalogFeatures.builder()
+ .with(CatalogFeatures.Feature.FILES, null)
+ .build();
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullUri() {
+ URI uri = null;
+ CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, uri);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullUri1() {
+ URI uri = null;
+ Catalog c = CatalogManager.catalog(FEATURES, uri);
+ }
+
+ String systemId = "http://www.sys00test.com/rewrite.dtd";
+ String publicId = "PUB-404";
+ String expected = "http://www.groupxmlbase.com/dtds/rewrite.dtd";
+ String errMsg = "Relative rewriteSystem with xml:base at group level failed";
+
+ /*
+ DataProvider: used to verify CatalogResolver's resolveEntity function.
+ Data columns:
+ catalog, systemId, publicId, expectedUri, msg
+ */
+ @DataProvider(name = "acceptedURI")
+ Object[][] getData() throws Exception {
+ String filename = "rewriteSystem_id.xml";
+ String urlFile = getClass().getResource(filename).toExternalForm();
+ String urlHttp = _remoteFilePath + "/jax-ws-catalog.xml";
+ String remoteXSD = _remoteFilePath + "/catalog/ws-addr.xsd";
+ File file = new File(CLS_DIR + "/JDK8171243.jar!/META-INF/jax-ws-catalog.xml");
+ String jarPath = SCHEME_JARFILE + file.toURI().toString();
+ String xsd = jarPath.substring(0, jarPath.lastIndexOf("/")) + "/catalog/ws-addr.xsd";
+
+ // create JAR file
+ try {
+ JarUtils.createJarFile(Paths.get(CLS_DIR + "/JDK8171243.jar"),
+ Paths.get(SRC_DIR + "/jar"), JAR_CONTENT);
+ } catch (IOException ex) {
+ Assert.fail("Failed to create JAR: " + ex.getMessage());
+ }
+
+ return new Object[][]{
+ // URL
+ {urlFile, systemId, publicId, expected, errMsg},
+ {urlHttp, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", remoteXSD, "http test failed."},
+ // JAR file
+ {jarPath, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", xsd, "jar file test failed."},
+ };
+ }
+
+ /*
+ * DataProvider: invalid catalog result in empty catalog
+ * Note: the difference from invalidInput is that invalidInput is syntactically
+ * rejected with an IAE.
+ */
+ @DataProvider(name = "invalidCatalog")
+ public Object[][] getInvalidCatalog() throws Exception {
+ String catalogUri = getClass().getResource("catalog_invalid.xml").toExternalForm();
+ return new Object[][]{
+ {catalogUri, "-//W3C//DTD XHTML 1.0 Strict//EN",
+ "The catalog is invalid, attempting to match the public entry shall return null."}
+ };
+ }
+
+ /*
+ * DataProvider: a list of invalid inputs, expects IAE
+ * Note: exclude null since NPE would have been expected
+ */
+ @DataProvider(name = "invalidInput")
+ public Object[][] getFiles() throws Exception {
+ String filename = "rewriteSystem_id.xml";
+ copyFile(Paths.get(SRC_DIR + "/" + filename), Paths.get(filename));
+ String absolutePath = getClass().getResource(filename).getFile();
+
+ return new Object[][]{
+ {""},
+ {"file:a/b\\c"},
+ {"file:/../../.."},
+ {"c:/te:t"},
+ {"c:/te?t"},
+ {"c/te*t"},
+ {"in|valid.txt"},
+ {"shema:invalid.txt"},
+ // relative file path
+ {filename},
+ // absolute file path
+ {absolutePath}
+ };
+ }
+
+ /*
+ DataProvider: a list of invalid inputs
+ */
+ @DataProvider(name = "nullTest")
+ public Object[][] getNull() throws Exception {
+
+ return new Object[][]{
+ {null},
+ };
+ }
+
+ void copyFile(Path src, Path target) throws Exception {
+
+ try (InputStream in = Files.newInputStream(src);
+ BufferedReader reader
+ = new BufferedReader(new InputStreamReader(in));
+ OutputStream out = new BufferedOutputStream(
+ Files.newOutputStream(target, CREATE, APPEND));
+ BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out))) {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ bw.write(line);
+ }
+ } catch (IOException x) {
+ throw new Exception(x.getMessage());
+ }
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogInvalidPathTest.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-package catalog;
-
-import javax.xml.catalog.CatalogFeatures;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/*
- * @test
- * @bug 8151154
- * @run testng/othervm catalog.CatalogInvalidPathTest
- * @summary Verifies that the CatalogFeatures' builder throws
- * IllegalArgumentException on invalid file inputs.
- * This test was splitted from CatalogTest.java due to
- * JDK-8168968, it has to only run without SecurityManager
- * because an ACE will be thrown for invalid path.
- */
-public class CatalogInvalidPathTest {
- /*
- DataProvider: for testing the verification of file paths by
- the CatalogFeatures builder
- */
- @DataProvider(name = "invalidPaths")
- public Object[][] getFiles() {
- return new Object[][]{
- {null},
- {""},
- {"file:a/b\\c"},
- {"file:/../../.."},
- {"c:/te:t"},
- {"c:/te?t"},
- {"c/te*t"},
- {"in|valid.txt"},
- {"shema:invalid.txt"},
- };
- }
-
- @Test(dataProvider = "invalidPaths", expectedExceptions = IllegalArgumentException.class)
- public void testFileInput(String file) {
- CatalogFeatures features = CatalogFeatures.builder()
- .with(CatalogFeatures.Feature.FILES, file)
- .build();
- }
-}
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,13 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
+import java.nio.file.Paths;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogResolver;
@@ -133,8 +140,8 @@
dtd_system = filepath + "system.dtd";
dtd_systemResolved = "<!ENTITY system \"resolved by an EntityHandler, rather than a Catalog\">";
- xml_catalog = filepath + "CatalogSupport.xml";
- xml_bogus_catalog = filepath + "CatalogSupport_bogus.xml";
+ xml_catalog = Paths.get(filepath + "CatalogSupport.xml").toUri().toASCIIString();
+ xml_bogus_catalog = Paths.get(filepath + "CatalogSupport_bogus.xml").toUri().toASCIIString();
xml_xInclude = "<?xml version=\"1.0\"?>\n" +
"<xinclude:include xmlns:xinclude=\"http://www.w3.org/2001/XInclude\"\n" +
@@ -997,4 +1004,35 @@
return null;
}
}
+
+ /**
+ * Simple policy implementation that grants a set of permissions to all code
+ * sources and protection domains.
+ */
+ static class SimplePolicy extends Policy {
+
+ private final Permissions perms;
+
+ public SimplePolicy(Permission... permissions) {
+ perms = new Permissions();
+ for (Permission permission : permissions) {
+ perms.add(permission);
+ }
+ }
+
+ @Override
+ public PermissionCollection getPermissions(CodeSource cs) {
+ return perms;
+ }
+
+ @Override
+ public PermissionCollection getPermissions(ProtectionDomain pd) {
+ return perms;
+ }
+
+ @Override
+ public boolean implies(ProtectionDomain pd, Permission p) {
+ return perms.implies(p);
+ }
+ }
}
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,17 +22,14 @@
*/
package catalog;
-import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
-import static jaxp.library.JAXPTestUtilities.setSystemProperty;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
+import java.net.URI;
import java.nio.file.Paths;
-
import javax.xml.XMLConstants;
import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException;
@@ -55,7 +52,8 @@
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
-
+import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
+import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@@ -95,10 +93,10 @@
* CatalogException is thrown.
*/
@Test(dataProvider = "getFeatures", expectedExceptions = CatalogException.class)
- public void testCircularRef(CatalogFeatures cf, String xml) {
+ public void testCircularRef(CatalogFeatures cf, String xml) throws Exception {
CatalogResolver catalogResolver = CatalogManager.catalogResolver(
cf,
- getClass().getResource(xml).getFile());
+ getClass().getResource(xml).toURI());
catalogResolver.resolve("anyuri", "");
}
@@ -108,14 +106,14 @@
*/
@DataProvider(name = "getFeatures")
public Object[][] getFeatures() {
-
+ String self = "catalogReferCircle-itself.xml";
+ String left = "catalogReferCircle-left.xml";
return new Object[][]{
- {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
- "catalogReferCircle-itself.xml"},
- {CatalogFeatures.defaults(), "catalogReferCircle-itself.xml"},
- {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
- "catalogReferCircle-left.xml"},
- {CatalogFeatures.defaults(), "catalogReferCircle-left.xml"},};
+ {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), self},
+ {CatalogFeatures.defaults(), self},
+ {CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), left},
+ {CatalogFeatures.defaults(), left}
+ };
}
/*
@@ -134,7 +132,7 @@
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
- public void supportEntityResolver(String catalogFile, String xml, String expected) throws Exception {
+ public void supportEntityResolver(URI catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@@ -150,7 +148,7 @@
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
- public void supportXMLResolver(String catalogFile, String xml, String expected) throws Exception {
+ public void supportXMLResolver(URI catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@@ -159,7 +157,7 @@
xifactory.setProperty(XMLInputFactory.IS_COALESCING, true);
xifactory.setProperty(XMLInputFactory.RESOLVER, cr);
File file = new File(xmlSource);
- String systemId = file.toURI().toString();
+ String systemId = file.toURI().toASCIIString();
InputStream entityxml = new FileInputStream(file);
XMLStreamReader streamReader = xifactory.createXMLStreamReader(systemId, entityxml);
String result = null;
@@ -183,7 +181,7 @@
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver")
- public void supportLSResourceResolver(String catalogFile, Source schemaSource) throws SAXException {
+ public void supportLSResourceResolver(URI catalogFile, Source schemaSource) throws SAXException {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@@ -199,7 +197,7 @@
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver1")
- public void supportLSResourceResolver1(String catalogFile, Source source) throws Exception {
+ public void supportLSResourceResolver1(URI catalogFile, Source source) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@@ -215,7 +213,7 @@
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportURIResolver")
- public void supportURIResolver(String catalogFile, Source xsl, Source xml, String expected) throws Exception {
+ public void supportURIResolver(URI catalogFile, Source xsl, Source xml, String expected) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@@ -235,9 +233,9 @@
catalog filepath, xml source file, expected result
*/
@DataProvider(name = "supportXMLResolver")
- public Object[][] supportXMLResolver() {
- String catalogFile = getClass().getResource("catalog.xml").getFile();
- String catalogFileUri = getClass().getResource("catalog_uri.xml").getFile();
+ public Object[][] supportXMLResolver() throws Exception {
+ URI catalogFile = getClass().getResource("catalog.xml").toURI();
+ URI catalogFileUri = getClass().getResource("catalog_uri.xml").toURI();
return new Object[][]{
{catalogFile, "system.xml", "Test system entry"},
@@ -263,9 +261,9 @@
catalog filepath, schema source file
*/
@DataProvider(name = "supportLSResourceResolver")
- public Object[][] supportLSResourceResolver() {
- String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
- String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
+ public Object[][] supportLSResourceResolver() throws Exception {
+ URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
+ URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
/*
* XMLSchema.xsd has a reference to XMLSchema.dtd which in turn refers to
@@ -287,9 +285,9 @@
catalog filepath, source file
*/
@DataProvider(name = "supportLSResourceResolver1")
- public Object[][] supportLSResourceResolver1() {
- String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
- String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
+ public Object[][] supportLSResourceResolver1() throws Exception {
+ URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
+ URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
/*
* val_test.xml has a reference to system.dtd and val_test.xsd
@@ -310,9 +308,9 @@
catalog filepath, xsl source, xml source file
*/
@DataProvider(name = "supportURIResolver")
- public Object[][] supportURIResolver() {
- String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
- String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
+ public Object[][] supportURIResolver() throws Exception {
+ URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
+ URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
SAXSource xslSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString()));
/*
@@ -353,8 +351,9 @@
* other cases in that test.
*/
@Test(dataProvider = "resolveUri")
- public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) {
- String catalogFile = getClass().getResource(cFile).getFile();
+ public void testMatch1(String cFile, String href, String expectedFile,
+ String expectedUri, String msg) throws Exception {
+ URI catalogFile = getClass().getResource(cFile).toURI();
CatalogResolver cur = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
Source source = cur.resolve(href, null);
Assert.assertNotNull(source, "Source returned is null");
@@ -368,15 +367,16 @@
*/
@Test(dataProvider = "hierarchyOfCatFilesData")
public void hierarchyOfCatFiles2(String systemId, String expectedUri) {
- String file1 = getClass().getResource("first_cat.xml").getFile();
- String file2 = getClass().getResource("second_cat.xml").getFile();
+ String file1 = getClass().getResource("first_cat.xml").toExternalForm();
+ String file2 = getClass().getResource("second_cat.xml").toExternalForm();
String files = file1 + ";" + file2;
try {
setSystemProperty(KEY_FILES, files);
CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults());
String sysId = catalogResolver.resolveEntity(null, systemId).getSystemId();
- Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"), "System ID match not right");
+ Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"),
+ "System ID match not right");
} finally {
clearSystemProperty(KEY_FILES);
}
@@ -390,8 +390,9 @@
* expected.
*/
@Test(dataProvider = "resolveEntity")
- public void testMatch1(String cfile, String prefer, String sysId, String pubId, String expectedUri, String expectedFile, String msg) {
- String catalogFile = getClass().getResource(cfile).getFile();
+ public void testMatch1(String cfile, String prefer, String sysId, String pubId,
+ String expectedUri, String expectedFile, String msg) throws Exception {
+ URI catalogFile = getClass().getResource(cfile).toURI();
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build();
CatalogResolver catalogResolver = CatalogManager.catalogResolver(features, catalogFile);
InputSource is = catalogResolver.resolveEntity(pubId, sysId);
@@ -406,9 +407,12 @@
* results as expected.
*/
@Test(dataProvider = "matchWithPrefer")
- public void matchWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
- String catalogFile = getClass().getResource(cfile).getFile();
- Catalog c = CatalogManager.catalog(CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(), catalogFile);
+ public void matchWithPrefer(String prefer, String cfile, String publicId,
+ String systemId, String expected) throws Exception {
+ URI catalogFile = getClass().getResource(cfile).toURI();
+ Catalog c = CatalogManager.catalog(
+ CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(),
+ catalogFile);
String result;
if (publicId != null && publicId.length() > 0) {
result = c.matchPublic(publicId);
@@ -430,8 +434,9 @@
* system entry is found.
*/
@Test(dataProvider = "resolveWithPrefer")
- public void resolveWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
- String catalogFile = getClass().getResource(cfile).getFile();
+ public void resolveWithPrefer(String prefer, String cfile, String publicId,
+ String systemId, String expected) throws Exception {
+ URI catalogFile = getClass().getResource(cfile).toURI();
CatalogFeatures f = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).with(CatalogFeatures.Feature.RESOLVE, "ignore").build();
CatalogResolver catalogResolver = CatalogManager.catalogResolver(f, catalogFile);
String result = catalogResolver.resolveEntity(publicId, systemId).getSystemId();
@@ -445,8 +450,8 @@
* be loaded is determined by the defer attribute.
*/
@Test(dataProvider = "invalidAltCatalogs", expectedExceptions = CatalogException.class)
- public void testDeferAltCatalogs(String file) {
- String catalogFile = getClass().getResource(file).getFile();
+ public void testDeferAltCatalogs(String file) throws Exception {
+ URI catalogFile = getClass().getResource(file).toURI();
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "true").build();
/*
Since the defer attribute is set to false in the specified catalog file,
@@ -462,8 +467,8 @@
* PREFER from Features API taking precedence over catalog file
*/
@Test
- public void testJDK8146237() {
- String catalogFile = getClass().getResource("JDK8146237_catalog.xml").getFile();
+ public void testJDK8146237() throws Exception {
+ URI catalogFile = getClass().getResource("JDK8146237_catalog.xml").toURI();
try {
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, "system").build();
@@ -482,8 +487,8 @@
Verifies that the resulting systemId does not contain duplicate slashes
*/
@Test
- public void testRewriteSystem() {
- String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
+ public void testRewriteSystem() throws Exception {
+ URI catalog = getClass().getResource("rewriteCatalog.xml").toURI();
try {
CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
@@ -500,8 +505,8 @@
Verifies that the resulting systemId does not contain duplicate slashes
*/
@Test
- public void testRewriteUri() {
- String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
+ public void testRewriteUri() throws Exception {
+ URI catalog = getClass().getResource("rewriteCatalog.xml").toURI();
try {
@@ -519,18 +524,18 @@
*/
@Test(expectedExceptions = NullPointerException.class)
public void testFeatureNull() {
- CatalogResolver resolver = CatalogManager.catalogResolver(null, "");
+ CatalogResolver resolver = CatalogManager.catalogResolver(null, null);
}
/*
@bug 8144966
- Verifies that passing null as the path will result in a NPE.
+ Verifies that passing null as the URI will result in a NPE.
*/
@Test(expectedExceptions = NullPointerException.class)
public void testPathNull() {
- String path = null;
- CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), path);
+ URI uri = null;
+ CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), uri);
}
/*
@@ -540,10 +545,11 @@
that matches the expected value.
*/
@Test(dataProvider = "catalog")
- public void testCatalogResolver(String test, String expected, String catalogFile, String xml, SAXParser saxParser) {
- String catalog = null;
+ public void testCatalogResolver(String test, String expected, String catalogFile,
+ String xml, SAXParser saxParser) throws Exception {
+ URI catalog = null;
if (catalogFile != null) {
- catalog = getClass().getResource(catalogFile).getFile();
+ catalog = getClass().getResource(catalogFile).toURI();
}
String url = getClass().getResource(xml).getFile();
try {
@@ -565,8 +571,8 @@
catalog is provided, the resolver will throw an exception by default.
*/
@Test
- public void testInvalidCatalog() {
- String catalog = getClass().getResource("catalog_invalid.xml").getFile();
+ public void testInvalidCatalog() throws Exception {
+ URI catalog = getClass().getResource("catalog_invalid.xml").toURI();
String test = "testInvalidCatalog";
try {
@@ -590,7 +596,7 @@
*/
@Test
public void testIgnoreInvalidCatalog() {
- String catalog = getClass().getResource("catalog_invalid.xml").getFile();
+ String catalog = getClass().getResource("catalog_invalid.xml").toExternalForm();
CatalogFeatures f = CatalogFeatures.builder()
.with(Feature.FILES, catalog)
.with(Feature.PREFER, "public")
@@ -600,7 +606,7 @@
String test = "testInvalidCatalog";
try {
- CatalogResolver resolver = CatalogManager.catalogResolver(f, "");
+ CatalogResolver resolver = CatalogManager.catalogResolver(f);
String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId();
System.out.println("testIgnoreInvalidCatalog: expected [null]");
System.out.println("testIgnoreInvalidCatalog: expected [null]");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/MANIFEST.MF Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Created-By: 9-ea (Oracle Corporation)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/catalog/ws-addr.xsd Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ W3C XML Schema defined in the Web Services Addressing 1.0 specification
+ http://www.w3.org/TR/ws-addr-core
+
+ Copyright © 2005 World Wide Web Consortium,
+
+ (Massachusetts Institute of Technology, European Research Consortium for
+ Informatics and Mathematics, Keio University). All Rights Reserved. This
+ work is distributed under the W3C® Software License [1] 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.
+
+ [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+ $Id: ws-addr.xsd,v 1.2 2008/07/23 13:38:16 plehegar Exp $
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.w3.org/2005/08/addressing" targetNamespace="http://www.w3.org/2005/08/addressing" blockDefault="#all" elementFormDefault="qualified" finalDefault="" attributeFormDefault="unqualified">
+
+ <!-- Constructs from the WS-Addressing Core -->
+
+ <xs:element name="EndpointReference" type="tns:EndpointReferenceType"/>
+ <xs:complexType name="EndpointReferenceType" mixed="false">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element ref="tns:ReferenceParameters" minOccurs="0"/>
+ <xs:element ref="tns:Metadata" minOccurs="0"/>
+ <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:complexType name="ReferenceParametersType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Metadata" type="tns:MetadataType"/>
+ <xs:complexType name="MetadataType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="MessageID" type="tns:AttributedURIType"/>
+ <xs:element name="RelatesTo" type="tns:RelatesToType"/>
+ <xs:complexType name="RelatesToType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="RelationshipType" type="tns:RelationshipTypeOpenEnum" use="optional" default="http://www.w3.org/2005/08/addressing/reply"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="RelationshipTypeOpenEnum">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="RelationshipType">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="ReplyTo" type="tns:EndpointReferenceType"/>
+ <xs:element name="From" type="tns:EndpointReferenceType"/>
+ <xs:element name="FaultTo" type="tns:EndpointReferenceType"/>
+ <xs:element name="To" type="tns:AttributedURIType"/>
+ <xs:element name="Action" type="tns:AttributedURIType"/>
+
+ <xs:complexType name="AttributedURIType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Constructs from the WS-Addressing SOAP binding -->
+
+ <xs:attribute name="IsReferenceParameter" type="xs:boolean"/>
+
+ <xs:simpleType name="FaultCodesOpenEnumType">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="FaultCodesType">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType"/>
+ <xs:complexType name="AttributedUnsignedLongType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeaderQName" type="tns:AttributedQNameType"/>
+ <xs:complexType name="AttributedQNameType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemIRI" type="tns:AttributedURIType"/>
+
+ <xs:element name="ProblemAction" type="tns:ProblemActionType"/>
+ <xs:complexType name="ProblemActionType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="tns:Action" minOccurs="0"/>
+ <xs:element name="SoapAction" minOccurs="0" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+</xs:schema>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/jax-ws-catalog.xml Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<catalog prefer="system" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+ <system systemId="http://www.w3.org/2006/03/addressing/ws-addr.xsd" uri="./catalog/ws-addr.xsd"/>
+</catalog>
\ No newline at end of file
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -37,6 +37,7 @@
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
@@ -74,11 +75,30 @@
* @run testng/othervm -DrunSecMngr=true transform.TransformerTest
* @run testng/othervm transform.TransformerTest
* @summary Transformer Tests
- * @bug 6272879 6305029 6505031 8150704 8162598 8169112 8169772
+ * @bug 6272879 6305029 6505031 8150704 8162598 8169112 8169631 8169772
*/
@Listeners({jaxp.library.FilePolicy.class})
public class TransformerTest {
+ // some global constants
+ private static final String LINE_SEPARATOR =
+ getSystemProperty("line.separator");
+
+ private static final String NAMESPACES =
+ "http://xml.org/sax/features/namespaces";
+
+ private static final String NAMESPACE_PREFIXES =
+ "http://xml.org/sax/features/namespace-prefixes";
+
+ private static abstract class TestTemplate {
+ protected void printSnippet(String title, String snippet) {
+ StringBuilder div = new StringBuilder();
+ for (int i = 0; i < title.length(); i++)
+ div.append("=");
+ System.out.println(title + "\n" + div + "\n" + snippet + "\n");
+ }
+ }
+
/**
* Reads the contents of the given file into a string.
* WARNING: this method adds a final line feed even if the last line of the file doesn't contain one.
@@ -101,44 +121,7 @@
}
}
- /**
- * Utility method for testBug8162598().
- * Provides a convenient way to check/assert the expected namespaces
- * of a Node and its siblings.
- *
- * @param test
- * The node to check
- * @param nstest
- * Expected namespace of the node
- * @param nsb
- * Expected namespace of the first sibling
- * @param nsc
- * Expected namespace of the first sibling of the first sibling
- */
- private void checkNodeNS8162598(Node test, String nstest, String nsb, String nsc) {
- String testNodeName = test.getNodeName();
- if (nstest == null) {
- Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
- } else {
- Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
- }
- Node b = test.getChildNodes().item(0);
- if (nsb == null) {
- Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
- } else {
- Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
- }
- Node c = b.getChildNodes().item(0);
- if (nsc == null) {
- Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
- } else {
- Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
- }
- }
-
private class XMLReaderFor6305029 implements XMLReader {
- private static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
- private static final String NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
private boolean namespaces = true;
private boolean namespacePrefixes = false;
private EntityResolver resolver;
@@ -235,8 +218,6 @@
*/
@Test
public final void testBug6272879() throws IOException, TransformerException {
- final String LINE_SEPARATOR = getSystemProperty("line.separator");
-
final String xsl =
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
@@ -349,9 +330,125 @@
Assert.assertTrue(s.contains("map1key1value") && s.contains("map2key1value"));
}
+ private static class Test8169631 extends TestTemplate {
+ private final static String xsl =
+ "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
+ " <xsl:template match=\"/\">" + LINE_SEPARATOR +
+ " <xsl:variable name=\"Counter\" select=\"count(//row)\"/>" + LINE_SEPARATOR +
+ " <xsl:variable name=\"AttribCounter\" select=\"count(//@attrib)\"/>" + LINE_SEPARATOR +
+ " <Counter><xsl:value-of select=\"$Counter\"/></Counter>" + LINE_SEPARATOR +
+ " <AttribCounter><xsl:value-of select=\"$AttribCounter\"/></AttribCounter>" + LINE_SEPARATOR +
+ " </xsl:template>" + LINE_SEPARATOR +
+ "</xsl:stylesheet>" + LINE_SEPARATOR;
+
+ private final static String sourceXml =
+ "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
+ "<envelope xmlns=\"http://www.sap.com/myns\" xmlns:sap=\"http://www.sap.com/myns\">" + LINE_SEPARATOR +
+ " <sap:row sap:attrib=\"a\">1</sap:row>" + LINE_SEPARATOR +
+ " <row attrib=\"b\">2</row>" + LINE_SEPARATOR +
+ " <row sap:attrib=\"c\">3</row>" + LINE_SEPARATOR +
+ "</envelope>" + LINE_SEPARATOR;
+
+ /**
+ * Utility method to print out transformation result and check values.
+ *
+ * @param type
+ * Text describing type of transformation
+ * @param result
+ * Resulting output of transformation
+ * @param elementCount
+ * Counter of elements to check
+ * @param attribCount
+ * Counter of attributes to check
+ */
+ private void verifyResult(String type, String result, int elementCount,
+ int attribCount)
+ {
+ printSnippet("Result of transformation from " + type + ":",
+ result);
+ Assert.assertEquals(
+ result.contains("<Counter>" + elementCount + "</Counter>"),
+ true, "Result of transformation from " + type +
+ " should have count of " + elementCount + " elements.");
+ Assert.assertEquals(
+ result.contains("<AttribCounter>" + attribCount +
+ "</AttribCounter>"), true, "Result of transformation from " +
+ type + " should have count of "+ attribCount + " attributes.");
+ }
+
+ public void run() throws IOException, TransformerException,
+ SAXException, ParserConfigurationException
+ {
+ printSnippet("Source:", sourceXml);
+
+ printSnippet("Stylesheet:", xsl);
+
+ // create default transformer (namespace aware)
+ TransformerFactory tf1 = TransformerFactory.newInstance();
+ ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
+ Transformer t1 = tf1.newTransformer(new StreamSource(bais));
+
+ // test transformation from stream source with namespace support
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ bais = new ByteArrayInputStream(sourceXml.getBytes());
+ t1.transform(new StreamSource(bais), new StreamResult(baos));
+ verifyResult("StreamSource with namespace support", baos.toString(), 0, 1);
+
+ // test transformation from DOM source with namespace support
+ bais.reset();
+ baos.reset();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ Document doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
+ t1.transform(new DOMSource(doc), new StreamResult(baos));
+ verifyResult("DOMSource with namespace support", baos.toString(), 0, 1);
+
+ // test transformation from DOM source without namespace support
+ bais.reset();
+ baos.reset();
+ dbf.setNamespaceAware(false);
+ doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
+ t1.transform(new DOMSource(doc), new StreamResult(baos));
+ verifyResult("DOMSource without namespace support", baos.toString(), 3, 3);
+
+ // test transformation from SAX source with namespace support
+ bais.reset();
+ baos.reset();
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ XMLReader xmlr = spf.newSAXParser().getXMLReader();
+ SAXSource saxS = new SAXSource(xmlr, new InputSource(bais));
+ t1.transform(saxS, new StreamResult(baos));
+ verifyResult("SAXSource with namespace support", baos.toString(), 0, 1);
+
+ // test transformation from SAX source without namespace support
+ bais.reset();
+ baos.reset();
+ spf.setNamespaceAware(false);
+ xmlr = spf.newSAXParser().getXMLReader();
+ saxS = new SAXSource(xmlr, new InputSource(bais));
+ t1.transform(saxS, new StreamResult(baos));
+ verifyResult("SAXSource without namespace support", baos.toString(), 3, 3);
+ }
+ }
+
+ /*
+ * @bug 8169631
+ * @summary Test combinations of namespace awareness settings on
+ * XSL transformations
+ */
+ @Test
+ public final void testBug8169631() throws IOException, SAXException,
+ TransformerException, ParserConfigurationException
+ {
+ new Test8169631().run();
+ }
+
/*
* @bug 8150704
- * @summary Test that XSL transformation with lots of temporary result trees will not run out of DTM IDs.
+ * @summary Test that XSL transformation with lots of temporary result
+ * trees will not run out of DTM IDs.
*/
@Test
public final void testBug8150704() throws TransformerException, IOException {
@@ -375,16 +472,8 @@
System.out.println("Passed.");
}
- /*
- * @bug 8162598
- * @summary Test XSLTC handling of namespaces, especially empty namespace definitions to reset the
- * default namespace
- */
- @Test
- public final void testBug8162598() throws IOException, TransformerException {
- final String LINE_SEPARATOR = getSystemProperty("line.separator");
-
- final String xsl =
+ private static class Test8162598 extends TestTemplate {
+ private static final String xsl =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR +
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
" <xsl:template match=\"/\">" + LINE_SEPARATOR +
@@ -402,39 +491,85 @@
" </xsl:template>" + LINE_SEPARATOR +
"</xsl:stylesheet>";
-
- final String sourceXml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
+ private static final String sourceXml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
+ /**
+ * Utility method for testBug8162598().
+ * Provides a convenient way to check/assert the expected namespaces
+ * of a Node and its siblings.
+ *
+ * @param test
+ * The node to check
+ * @param nstest
+ * Expected namespace of the node
+ * @param nsb
+ * Expected namespace of the first sibling
+ * @param nsc
+ * Expected namespace of the first sibling of the first sibling
+ */
- System.out.println("Stylesheet:");
- System.out.println("=============================");
- System.out.println(xsl);
- System.out.println();
-
- System.out.println("Source before transformation:");
- System.out.println("=============================");
- System.out.println(sourceXml);
- System.out.println();
+ private void checkNodeNS(Node test, String nstest, String nsb, String nsc) {
+ String testNodeName = test.getNodeName();
+ if (nstest == null) {
+ Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
+ } else {
+ Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
+ }
+ Node b = test.getChildNodes().item(0);
+ if (nsb == null) {
+ Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
+ } else {
+ Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
+ }
+ Node c = b.getChildNodes().item(0);
+ if (nsc == null) {
+ Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
+ } else {
+ Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
+ }
+ }
- // transform to DOM result
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
- DOMResult result = new DOMResult();
- t.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())), result);
- Document document = (Document)result.getNode();
+ public void run() throws IOException, TransformerException {
+ printSnippet("Source:", sourceXml);
+
+ printSnippet("Stylesheet:", xsl);
+
+ // transform to DOM result
+ TransformerFactory tf = TransformerFactory.newInstance();
+ ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
+ Transformer t = tf.newTransformer(new StreamSource(bais));
+ DOMResult result = new DOMResult();
+ bais = new ByteArrayInputStream(sourceXml.getBytes());
+ t.transform(new StreamSource(bais), result);
+ Document document = (Document)result.getNode();
+
+ System.out.println("Result after transformation:");
+ System.out.println("============================");
+ OutputFormat format = new OutputFormat();
+ format.setIndenting(true);
+ new XMLSerializer(System.out, format).serialize(document);
+ System.out.println();
- System.out.println("Result after transformation:");
- System.out.println("============================");
- OutputFormat format = new OutputFormat();
- format.setIndenting(true);
- new XMLSerializer(System.out, format).serialize(document);
- System.out.println();
- checkNodeNS8162598(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
- checkNodeNS8162598(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
- checkNodeNS8162598(document.getElementsByTagName("test3").item(0), null, null, null);
- checkNodeNS8162598(document.getElementsByTagName("test4").item(0), null, null, null);
- checkNodeNS8162598(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
- Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(), "unexpected namespace for test6");
+ checkNodeNS(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
+ checkNodeNS(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
+ checkNodeNS(document.getElementsByTagName("test3").item(0), null, null, null);
+ checkNodeNS(document.getElementsByTagName("test4").item(0), null, null, null);
+ checkNodeNS(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
+ Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(),
+ "unexpected namespace for test6");
+ }
+ }
+
+ /*
+ * @bug 8162598
+ * @summary Test XSLTC handling of namespaces, especially empty namespace
+ * definitions to reset the default namespace
+ */
+ @Test
+ public final void testBug8162598() throws IOException,
+ TransformerException
+ {
+ new Test8162598().run();
}
/**
--- a/jaxws/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -397,3 +397,5 @@
72554d319b474b3636c7d02fe3c110254d111b1a jdk-9+149
77e4e30d9d111272cd4a45a2203e8f570d40b12e jdk-9+150
c48b4d4768b1c2b8fe5d1a844ca13732e5dfbe2a jdk-9+151
+6f8fb1cf7e5f61c40dcc3654f9a623c505f6de1f jdk-9+152
+7a532a9a227137155b905341d4b99939db51220e jdk-9+153
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/DetailImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/DetailImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -47,13 +47,13 @@
public DetailEntry addDetailEntry(Name name) throws SOAPException {
DetailEntry entry = createDetailEntry(name);
addNode(entry);
- return (DetailEntry) circumventBug5034339(entry);
+ return entry;
}
public DetailEntry addDetailEntry(QName qname) throws SOAPException {
DetailEntry entry = createDetailEntry(qname);
addNode(entry);
- return (DetailEntry) circumventBug5034339(entry);
+ return entry;
}
protected SOAPElement addElement(Name name) throws SOAPException {
@@ -119,28 +119,4 @@
return true;
}
- //overriding this method since the only two uses of this method
- // are in ElementImpl and DetailImpl
- //whereas the original base impl does the correct job for calls to it inside ElementImpl
- // But it would not work for DetailImpl.
- protected SOAPElement circumventBug5034339(SOAPElement element) {
-
- Name elementName = element.getElementName();
- if (!isNamespaceQualified(elementName)) {
- String prefix = elementName.getPrefix();
- String defaultNamespace = getNamespaceURI(prefix);
- if (defaultNamespace != null) {
- Name newElementName =
- NameImpl.create(
- elementName.getLocalName(),
- elementName.getPrefix(),
- defaultNamespace);
- SOAPElement newElement = createDetailEntry(newElementName);
- replaceChild(newElement, element);
- return newElement;
- }
- }
- return element;
- }
-
}
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/ElementImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/ElementImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -127,8 +127,11 @@
}
public SOAPElement addChildElement(String localName) throws SOAPException {
- return (SOAPElement) addChildElement(
- NameImpl.createFromUnqualifiedName(localName));
+ String nsUri = getNamespaceURI("");
+ Name name = (nsUri == null || nsUri.isEmpty())
+ ? NameImpl.createFromUnqualifiedName(localName)
+ : NameImpl.createFromQualifiedName(localName, nsUri);
+ return addChildElement(name);
}
public SOAPElement addChildElement(String localName, String prefix)
@@ -372,13 +375,13 @@
protected SOAPElement addElement(Name name) throws SOAPException {
SOAPElement newElement = createElement(name);
addNode(newElement);
- return circumventBug5034339(newElement);
+ return newElement;
}
protected SOAPElement addElement(QName name) throws SOAPException {
SOAPElement newElement = createElement(name);
addNode(newElement);
- return circumventBug5034339(newElement);
+ return newElement;
}
protected SOAPElement createElement(Name name) {
@@ -1226,26 +1229,6 @@
return !"".equals(name.getNamespaceURI());
}
- protected SOAPElement circumventBug5034339(SOAPElement element) {
-
- Name elementName = element.getElementName();
- if (!isNamespaceQualified(elementName)) {
- String prefix = elementName.getPrefix();
- String defaultNamespace = getNamespaceURI(prefix);
- if (defaultNamespace != null) {
- Name newElementName =
- NameImpl.create(
- elementName.getLocalName(),
- elementName.getPrefix(),
- defaultNamespace);
- SOAPElement newElement = createElement(newElementName);
- replaceChild(newElement, element);
- return newElement;
- }
- }
- return element;
- }
-
//TODO: This is a temporary SAAJ workaround for optimizing XWS
// should be removed once the corresponding JAXP bug is fixed
// It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
package com.sun.xml.internal.messaging.saaj.util.stax;
+import java.util.Iterator;
import java.util.Arrays;
-import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@@ -42,6 +44,17 @@
/**
* SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface.
*
+ * <p>
+ * Defers creation of SOAPElement until all the aspects of the name of the element are known.
+ * In some cases, the namespace uri is indicated only by the {@link #writeNamespace(String, String)} call.
+ * After opening an element ({@code writeStartElement}, {@code writeEmptyElement} methods), all attributes
+ * and namespace assignments are retained within {@link DeferredElement} object ({@code deferredElement} field).
+ * As soon as any other method than {@code writeAttribute}, {@code writeNamespace}, {@code writeDefaultNamespace}
+ * or {@code setNamespace} is called, the contents of {@code deferredElement} is transformed into new SOAPElement
+ * (which is appropriately inserted into the SOAPMessage under construction).
+ * This mechanism is necessary to fix JDK-8159058 issue.
+ * </p>
+ *
* @author shih-chang.chen@oracle.com
*/
public class SaajStaxWriter implements XMLStreamWriter {
@@ -49,6 +62,7 @@
protected SOAPMessage soap;
protected String envURI;
protected SOAPElement currentElement;
+ protected DeferredElement deferredElement;
static final protected String Envelope = "Envelope";
static final protected String Header = "Header";
@@ -58,6 +72,7 @@
public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException {
soap = msg;
this.envURI = uri;
+ this.deferredElement = new DeferredElement();
}
public SOAPMessage getSOAPMessage() {
@@ -70,11 +85,8 @@
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
- try {
- currentElement = currentElement.addChildElement(localName);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
- }
+ currentElement = deferredElement.flushTo(currentElement);
+ deferredElement.setLocalName(localName);
}
@Override
@@ -84,8 +96,10 @@
@Override
public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException {
- try {
- if (envURI.equals(ns)) {
+ currentElement = deferredElement.flushTo(currentElement);
+
+ if (envURI.equals(ns)) {
+ try {
if (Envelope.equals(ln)) {
currentElement = getEnvelope();
fixPrefix(prefix);
@@ -99,13 +113,16 @@
fixPrefix(prefix);
return;
}
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
}
- currentElement = (prefix == null) ?
- currentElement.addChildElement(new QName(ns, ln)) :
- currentElement.addChildElement(ln, prefix, ns);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+
}
+
+ deferredElement.setLocalName(ln);
+ deferredElement.setNamespaceUri(ns);
+ deferredElement.setPrefix(prefix);
+
}
private void fixPrefix(final String prfx) throws XMLStreamException {
@@ -136,11 +153,13 @@
@Override
public void writeEndElement() throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
if (currentElement != null) currentElement = currentElement.getParentElement();
}
@Override
public void writeEndDocument() throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
}
@Override
@@ -158,19 +177,14 @@
@Override
public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException {
- try {
- if (ns == null) {
- if (prefix == null && xmlns.equals(ln)) {
- currentElement.addNamespaceDeclaration("", value);
- } else {
- currentElement.setAttributeNS("", ln, value);
- }
+ if (ns == null && prefix == null && xmlns.equals(ln)) {
+ writeNamespace("", value);
+ } else {
+ if (deferredElement.isInitialized()) {
+ deferredElement.addAttribute(prefix, ns, ln, value);
} else {
- QName name = (prefix == null) ? new QName(ns, ln) : new QName(ns, ln, prefix);
- currentElement.addAttribute(name, value);
+ addAttibuteToElement(currentElement, prefix, ns, ln, value);
}
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
}
}
@@ -181,16 +195,16 @@
@Override
public void writeNamespace(String prefix, final String uri) throws XMLStreamException {
-
// make prefix default if null or "xmlns" (according to javadoc)
- if (prefix == null || "xmlns".equals(prefix)) {
- prefix = "";
- }
-
- try {
- currentElement.addNamespaceDeclaration(prefix, uri);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+ String thePrefix = prefix == null || "xmlns".equals(prefix) ? "" : prefix;
+ if (deferredElement.isInitialized()) {
+ deferredElement.addNamespaceDeclaration(thePrefix, uri);
+ } else {
+ try {
+ currentElement.addNamespaceDeclaration(thePrefix, uri);
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
}
}
@@ -201,35 +215,40 @@
@Override
public void writeComment(final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Comment c = soap.getSOAPPart().createComment(data);
currentElement.appendChild(c);
}
@Override
public void writeProcessingInstruction(final String target) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, "");
currentElement.appendChild(n);
}
@Override
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, data);
currentElement.appendChild(n);
}
@Override
public void writeCData(final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createCDATASection(data);
currentElement.appendChild(n);
}
@Override
public void writeDTD(final String dtd) throws XMLStreamException {
- //TODO ... Don't do anything here
+ currentElement = deferredElement.flushTo(currentElement);
}
@Override
public void writeEntityRef(final String name) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createEntityReference(name);
currentElement.appendChild(n);
}
@@ -257,6 +276,7 @@
@Override
public void writeCharacters(final String text) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
try {
currentElement.addTextNode(text);
} catch (SOAPException e) {
@@ -266,6 +286,7 @@
@Override
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len);
try {
currentElement.addTextNode(new String(chr));
@@ -281,10 +302,16 @@
@Override
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
- try {
- this.currentElement.addNamespaceDeclaration(prefix, uri);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+ // TODO: this in fact is not what would be expected from XMLStreamWriter
+ // (e.g. XMLStreamWriter for writing to output stream does not write anything as result of
+ // this method, it just rememebers that given prefix is associated with the given uri
+ // for the scope; to actually declare the prefix assignment in the resulting XML, one
+ // needs to call writeNamespace(...) method
+ // Kept for backwards compatibility reasons - this might be worth of further investigation.
+ if (deferredElement.isInitialized()) {
+ deferredElement.addNamespaceDeclaration(prefix, uri);
+ } else {
+ throw new XMLStreamException("Namespace not associated with any element");
}
}
@@ -331,4 +358,209 @@
}
};
}
+
+ static void addAttibuteToElement(SOAPElement element, String prefix, String ns, String ln, String value)
+ throws XMLStreamException {
+ try {
+ if (ns == null) {
+ element.setAttributeNS("", ln, value);
+ } else {
+ QName name = prefix == null ? new QName(ns, ln) : new QName(ns, ln, prefix);
+ element.addAttribute(name, value);
+ }
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+
+ /**
+ * Holds details of element that needs to be deferred in order to manage namespace assignments correctly.
+ *
+ * <p>
+ * An instance of can be set with all the aspects of the element name (local name, prefix, namespace uri).
+ * Attributes and namespace declarations (special case of attribute) can be added.
+ * Namespace declarations are handled so that the element namespace is updated if it is implied by the namespace
+ * declaration and the namespace was not set to non-{@code null} value previously.
+ * </p>
+ *
+ * <p>
+ * The state of this object can be {@link #flushTo(SOAPElement) flushed} to SOAPElement - new SOAPElement will
+ * be added a child element; the new element will have exactly the shape as represented by the state of this
+ * object. Note that the {@link #flushTo(SOAPElement)} method does nothing
+ * (and returns the argument immediately) if the state of this object is not initialized
+ * (i.e. local name is null).
+ * </p>
+ *
+ * @author ondrej.cerny@oracle.com
+ */
+ static class DeferredElement {
+ private String prefix;
+ private String localName;
+ private String namespaceUri;
+ private final List<NamespaceDeclaration> namespaceDeclarations;
+ private final List<AttributeDeclaration> attributeDeclarations;
+
+ DeferredElement() {
+ this.namespaceDeclarations = new LinkedList<NamespaceDeclaration>();
+ this.attributeDeclarations = new LinkedList<AttributeDeclaration>();
+ reset();
+ }
+
+
+ /**
+ * Set prefix of the element.
+ * @param prefix namespace prefix
+ */
+ public void setPrefix(final String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Set local name of the element.
+ *
+ * <p>
+ * This method initializes the element.
+ * </p>
+ *
+ * @param localName local name {@code not null}
+ */
+ public void setLocalName(final String localName) {
+ if (localName == null) {
+ throw new IllegalArgumentException("localName can not be null");
+ }
+ this.localName = localName;
+ }
+
+ /**
+ * Set namespace uri.
+ *
+ * @param namespaceUri namespace uri
+ */
+ public void setNamespaceUri(final String namespaceUri) {
+ this.namespaceUri = namespaceUri;
+ }
+
+ /**
+ * Adds namespace prefix assignment to the element.
+ *
+ * @param prefix prefix (not {@code null})
+ * @param namespaceUri namespace uri
+ */
+ public void addNamespaceDeclaration(final String prefix, final String namespaceUri) {
+ if (null == this.namespaceUri && null != namespaceUri && prefix.equals(emptyIfNull(this.prefix))) {
+ this.namespaceUri = namespaceUri;
+ }
+ this.namespaceDeclarations.add(new NamespaceDeclaration(prefix, namespaceUri));
+ }
+
+ /**
+ * Adds attribute to the element.
+ * @param prefix prefix
+ * @param ns namespace
+ * @param ln local name
+ * @param value value
+ */
+ public void addAttribute(final String prefix, final String ns, final String ln, final String value) {
+ if (ns == null && prefix == null && xmlns.equals(ln)) {
+ this.addNamespaceDeclaration(prefix, value);
+ } else {
+ this.attributeDeclarations.add(new AttributeDeclaration(prefix, ns, ln, value));
+ }
+ }
+
+ /**
+ * Flushes state of this element to the {@code target} element.
+ *
+ * <p>
+ * If this element is initialized then it is added with all the namespace declarations and attributes
+ * to the {@code target} element as a child. The state of this element is reset to uninitialized.
+ * The newly added element object is returned.
+ * </p>
+ * <p>
+ * If this element is not initialized then the {@code target} is returned immediately, nothing else is done.
+ * </p>
+ *
+ * @param target target element
+ * @return {@code target} or new element
+ * @throws XMLStreamException on error
+ */
+ public SOAPElement flushTo(final SOAPElement target) throws XMLStreamException {
+ try {
+ if (this.localName != null) {
+ // add the element appropriately (based on namespace declaration)
+ final SOAPElement newElement;
+ if (this.namespaceUri == null) {
+ // add element with inherited scope
+ newElement = target.addChildElement(this.localName);
+ } else if (prefix == null) {
+ newElement = target.addChildElement(new QName(this.namespaceUri, this.localName));
+ } else {
+ newElement = target.addChildElement(this.localName, this.prefix, this.namespaceUri);
+ }
+ // add namespace declarations
+ for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
+ target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
+ }
+ // add attribute declarations
+ for (AttributeDeclaration attribute : this.attributeDeclarations) {
+ addAttibuteToElement(newElement,
+ attribute.prefix, attribute.namespaceUri, attribute.localName, attribute.value);
+ }
+ // reset state
+ this.reset();
+
+ return newElement;
+ } else {
+ return target;
+ }
+ // else after reset state -> not initialized
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+
+ /**
+ * Is the element initialized?
+ * @return boolean indicating whether it was initialized after last flush
+ */
+ public boolean isInitialized() {
+ return this.localName != null;
+ }
+
+ private void reset() {
+ this.localName = null;
+ this.prefix = null;
+ this.namespaceUri = null;
+ this.namespaceDeclarations.clear();
+ this.attributeDeclarations.clear();
+ }
+
+ private static String emptyIfNull(String s) {
+ return s == null ? "" : s;
+ }
+ }
+
+ static class NamespaceDeclaration {
+ final String prefix;
+ final String namespaceUri;
+
+ NamespaceDeclaration(String prefix, String namespaceUri) {
+ this.prefix = prefix;
+ this.namespaceUri = namespaceUri;
+ }
+ }
+
+ static class AttributeDeclaration {
+ final String prefix;
+ final String namespaceUri;
+ final String localName;
+ final String value;
+
+ AttributeDeclaration(String prefix, String namespaceUri, String localName, String value) {
+ this.prefix = prefix;
+ this.namespaceUri = namespaceUri;
+ this.localName = localName;
+ this.value = value;
+ }
+ }
}
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
package com.sun.xml.internal.ws.api.message.saaj;
+import java.util.Iterator;
import java.util.Arrays;
-import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@@ -42,6 +44,17 @@
/**
* SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface.
*
+ * <p>
+ * Defers creation of SOAPElement until all the aspects of the name of the element are known.
+ * In some cases, the namespace uri is indicated only by the {@link #writeNamespace(String, String)} call.
+ * After opening an element ({@code writeStartElement}, {@code writeEmptyElement} methods), all attributes
+ * and namespace assignments are retained within {@link DeferredElement} object ({@code deferredElement} field).
+ * As soon as any other method than {@code writeAttribute}, {@code writeNamespace}, {@code writeDefaultNamespace}
+ * or {@code setNamespace} is called, the contents of {@code deferredElement} is transformed into new SOAPElement
+ * (which is appropriately inserted into the SOAPMessage under construction).
+ * This mechanism is necessary to fix JDK-8159058 issue.
+ * </p>
+ *
* @author shih-chang.chen@oracle.com
*/
public class SaajStaxWriter implements XMLStreamWriter {
@@ -49,6 +62,7 @@
protected SOAPMessage soap;
protected String envURI;
protected SOAPElement currentElement;
+ protected DeferredElement deferredElement;
static final protected String Envelope = "Envelope";
static final protected String Header = "Header";
@@ -58,6 +72,7 @@
public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException {
soap = msg;
this.envURI = uri;
+ this.deferredElement = new DeferredElement();
}
public SOAPMessage getSOAPMessage() {
@@ -70,11 +85,8 @@
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
- try {
- currentElement = currentElement.addChildElement(localName);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
- }
+ currentElement = deferredElement.flushTo(currentElement);
+ deferredElement.setLocalName(localName);
}
@Override
@@ -84,8 +96,10 @@
@Override
public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException {
- try {
- if (envURI.equals(ns)) {
+ currentElement = deferredElement.flushTo(currentElement);
+
+ if (envURI.equals(ns)) {
+ try {
if (Envelope.equals(ln)) {
currentElement = getEnvelope();
fixPrefix(prefix);
@@ -99,13 +113,16 @@
fixPrefix(prefix);
return;
}
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
}
- currentElement = (prefix == null) ?
- currentElement.addChildElement(new QName(ns, ln)) :
- currentElement.addChildElement(ln, prefix, ns);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+
}
+
+ deferredElement.setLocalName(ln);
+ deferredElement.setNamespaceUri(ns);
+ deferredElement.setPrefix(prefix);
+
}
private void fixPrefix(final String prfx) throws XMLStreamException {
@@ -136,11 +153,13 @@
@Override
public void writeEndElement() throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
if (currentElement != null) currentElement = currentElement.getParentElement();
}
@Override
public void writeEndDocument() throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
}
@Override
@@ -158,19 +177,14 @@
@Override
public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException {
- try {
- if (ns == null) {
- if (prefix == null && xmlns.equals(ln)) {
- currentElement.addNamespaceDeclaration("", value);
- } else {
- currentElement.setAttributeNS("", ln, value);
- }
+ if (ns == null && prefix == null && xmlns.equals(ln)) {
+ writeNamespace("", value);
+ } else {
+ if (deferredElement.isInitialized()) {
+ deferredElement.addAttribute(prefix, ns, ln, value);
} else {
- QName name = (prefix == null) ? new QName(ns, ln) : new QName(ns, ln, prefix);
- currentElement.addAttribute(name, value);
+ addAttibuteToElement(currentElement, prefix, ns, ln, value);
}
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
}
}
@@ -181,16 +195,16 @@
@Override
public void writeNamespace(String prefix, final String uri) throws XMLStreamException {
-
// make prefix default if null or "xmlns" (according to javadoc)
- if (prefix == null || "xmlns".equals(prefix)) {
- prefix = "";
- }
-
- try {
- currentElement.addNamespaceDeclaration(prefix, uri);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+ String thePrefix = prefix == null || "xmlns".equals(prefix) ? "" : prefix;
+ if (deferredElement.isInitialized()) {
+ deferredElement.addNamespaceDeclaration(thePrefix, uri);
+ } else {
+ try {
+ currentElement.addNamespaceDeclaration(thePrefix, uri);
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
}
}
@@ -201,35 +215,40 @@
@Override
public void writeComment(final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Comment c = soap.getSOAPPart().createComment(data);
currentElement.appendChild(c);
}
@Override
public void writeProcessingInstruction(final String target) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, "");
currentElement.appendChild(n);
}
@Override
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, data);
currentElement.appendChild(n);
}
@Override
public void writeCData(final String data) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createCDATASection(data);
currentElement.appendChild(n);
}
@Override
public void writeDTD(final String dtd) throws XMLStreamException {
- //TODO ... Don't do anything here
+ currentElement = deferredElement.flushTo(currentElement);
}
@Override
public void writeEntityRef(final String name) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createEntityReference(name);
currentElement.appendChild(n);
}
@@ -257,6 +276,7 @@
@Override
public void writeCharacters(final String text) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
try {
currentElement.addTextNode(text);
} catch (SOAPException e) {
@@ -266,6 +286,7 @@
@Override
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
+ currentElement = deferredElement.flushTo(currentElement);
char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len);
try {
currentElement.addTextNode(new String(chr));
@@ -281,10 +302,16 @@
@Override
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
- try {
- this.currentElement.addNamespaceDeclaration(prefix, uri);
- } catch (SOAPException e) {
- throw new XMLStreamException(e);
+ // TODO: this in fact is not what would be expected from XMLStreamWriter
+ // (e.g. XMLStreamWriter for writing to output stream does not write anything as result of
+ // this method, it just rememebers that given prefix is associated with the given uri
+ // for the scope; to actually declare the prefix assignment in the resulting XML, one
+ // needs to call writeNamespace(...) method
+ // Kept for backwards compatibility reasons - this might be worth of further investigation.
+ if (deferredElement.isInitialized()) {
+ deferredElement.addNamespaceDeclaration(prefix, uri);
+ } else {
+ throw new XMLStreamException("Namespace not associated with any element");
}
}
@@ -315,12 +342,12 @@
return currentElement.lookupPrefix(namespaceURI);
}
public Iterator getPrefixes(final String namespaceURI) {
- return new Iterator() {
+ return new Iterator<String>() {
String prefix = getPrefix(namespaceURI);
public boolean hasNext() {
return (prefix != null);
}
- public Object next() {
+ public String next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
String next = prefix;
prefix = null;
@@ -331,4 +358,209 @@
}
};
}
+
+ static void addAttibuteToElement(SOAPElement element, String prefix, String ns, String ln, String value)
+ throws XMLStreamException {
+ try {
+ if (ns == null) {
+ element.setAttributeNS("", ln, value);
+ } else {
+ QName name = prefix == null ? new QName(ns, ln) : new QName(ns, ln, prefix);
+ element.addAttribute(name, value);
+ }
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+
+ /**
+ * Holds details of element that needs to be deferred in order to manage namespace assignments correctly.
+ *
+ * <p>
+ * An instance of can be set with all the aspects of the element name (local name, prefix, namespace uri).
+ * Attributes and namespace declarations (special case of attribute) can be added.
+ * Namespace declarations are handled so that the element namespace is updated if it is implied by the namespace
+ * declaration and the namespace was not set to non-{@code null} value previously.
+ * </p>
+ *
+ * <p>
+ * The state of this object can be {@link #flushTo(SOAPElement) flushed} to SOAPElement - new SOAPElement will
+ * be added a child element; the new element will have exactly the shape as represented by the state of this
+ * object. Note that the {@link #flushTo(SOAPElement)} method does nothing
+ * (and returns the argument immediately) if the state of this object is not initialized
+ * (i.e. local name is null).
+ * </p>
+ *
+ * @author ondrej.cerny@oracle.com
+ */
+ static class DeferredElement {
+ private String prefix;
+ private String localName;
+ private String namespaceUri;
+ private final List<NamespaceDeclaration> namespaceDeclarations;
+ private final List<AttributeDeclaration> attributeDeclarations;
+
+ DeferredElement() {
+ this.namespaceDeclarations = new LinkedList<NamespaceDeclaration>();
+ this.attributeDeclarations = new LinkedList<AttributeDeclaration>();
+ reset();
+ }
+
+
+ /**
+ * Set prefix of the element.
+ * @param prefix namespace prefix
+ */
+ public void setPrefix(final String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Set local name of the element.
+ *
+ * <p>
+ * This method initializes the element.
+ * </p>
+ *
+ * @param localName local name {@code not null}
+ */
+ public void setLocalName(final String localName) {
+ if (localName == null) {
+ throw new IllegalArgumentException("localName can not be null");
+ }
+ this.localName = localName;
+ }
+
+ /**
+ * Set namespace uri.
+ *
+ * @param namespaceUri namespace uri
+ */
+ public void setNamespaceUri(final String namespaceUri) {
+ this.namespaceUri = namespaceUri;
+ }
+
+ /**
+ * Adds namespace prefix assignment to the element.
+ *
+ * @param prefix prefix (not {@code null})
+ * @param namespaceUri namespace uri
+ */
+ public void addNamespaceDeclaration(final String prefix, final String namespaceUri) {
+ if (null == this.namespaceUri && null != namespaceUri && prefix.equals(emptyIfNull(this.prefix))) {
+ this.namespaceUri = namespaceUri;
+ }
+ this.namespaceDeclarations.add(new NamespaceDeclaration(prefix, namespaceUri));
+ }
+
+ /**
+ * Adds attribute to the element.
+ * @param prefix prefix
+ * @param ns namespace
+ * @param ln local name
+ * @param value value
+ */
+ public void addAttribute(final String prefix, final String ns, final String ln, final String value) {
+ if (ns == null && prefix == null && xmlns.equals(ln)) {
+ this.addNamespaceDeclaration(prefix, value);
+ } else {
+ this.attributeDeclarations.add(new AttributeDeclaration(prefix, ns, ln, value));
+ }
+ }
+
+ /**
+ * Flushes state of this element to the {@code target} element.
+ *
+ * <p>
+ * If this element is initialized then it is added with all the namespace declarations and attributes
+ * to the {@code target} element as a child. The state of this element is reset to uninitialized.
+ * The newly added element object is returned.
+ * </p>
+ * <p>
+ * If this element is not initialized then the {@code target} is returned immediately, nothing else is done.
+ * </p>
+ *
+ * @param target target element
+ * @return {@code target} or new element
+ * @throws XMLStreamException on error
+ */
+ public SOAPElement flushTo(final SOAPElement target) throws XMLStreamException {
+ try {
+ if (this.localName != null) {
+ // add the element appropriately (based on namespace declaration)
+ final SOAPElement newElement;
+ if (this.namespaceUri == null) {
+ // add element with inherited scope
+ newElement = target.addChildElement(this.localName);
+ } else if (prefix == null) {
+ newElement = target.addChildElement(new QName(this.namespaceUri, this.localName));
+ } else {
+ newElement = target.addChildElement(this.localName, this.prefix, this.namespaceUri);
+ }
+ // add namespace declarations
+ for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
+ target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
+ }
+ // add attribute declarations
+ for (AttributeDeclaration attribute : this.attributeDeclarations) {
+ addAttibuteToElement(newElement,
+ attribute.prefix, attribute.namespaceUri, attribute.localName, attribute.value);
+ }
+ // reset state
+ this.reset();
+
+ return newElement;
+ } else {
+ return target;
+ }
+ // else after reset state -> not initialized
+ } catch (SOAPException e) {
+ throw new XMLStreamException(e);
+ }
+ }
+
+ /**
+ * Is the element initialized?
+ * @return boolean indicating whether it was initialized after last flush
+ */
+ public boolean isInitialized() {
+ return this.localName != null;
+ }
+
+ private void reset() {
+ this.localName = null;
+ this.prefix = null;
+ this.namespaceUri = null;
+ this.namespaceDeclarations.clear();
+ this.attributeDeclarations.clear();
+ }
+
+ private static String emptyIfNull(String s) {
+ return s == null ? "" : s;
+ }
+ }
+
+ static class NamespaceDeclaration {
+ final String prefix;
+ final String namespaceUri;
+
+ NamespaceDeclaration(String prefix, String namespaceUri) {
+ this.prefix = prefix;
+ this.namespaceUri = namespaceUri;
+ }
+ }
+
+ static class AttributeDeclaration {
+ final String prefix;
+ final String namespaceUri;
+ final String localName;
+ final String value;
+
+ AttributeDeclaration(String prefix, String namespaceUri, String localName, String value) {
+ this.prefix = prefix;
+ this.namespaceUri = namespaceUri;
+ this.localName = localName;
+ this.value = value;
+ }
+ }
}
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -33,6 +33,7 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
+import java.net.URI;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -332,13 +333,13 @@
* (com.sun.org.apache.xml.internal) for modular runtime.
*/
private static EntityResolver createCatalogResolver(ArrayList<URL> urls) throws Exception {
- // Prepare array of catalog paths
- String[] paths = urls.stream()
- .map(u -> u.toExternalForm())
- .toArray(c -> new String[c]);
+ // Prepare array of catalog URIs
+ URI[] uris = urls.stream()
+ .map(u -> URI.create(u.toExternalForm()))
+ .toArray(URI[]::new);
//Create CatalogResolver with new JDK9+ API
- return (EntityResolver) CatalogManager.catalogResolver(catalogFeatures, paths);
+ return (EntityResolver) CatalogManager.catalogResolver(catalogFeatures, uris);
}
// Cache CatalogFeatures instance for future usages.
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -777,13 +777,13 @@
* Adds a new catalog file.
*/
public void addCatalog(File catalogFile) throws IOException {
- String newUrl = catalogFile.getPath();
+ URI newUrl = catalogFile.toURI();
if (!catalogUrls.contains(newUrl)) {
catalogUrls.add(newUrl);
}
try {
entityResolver = CatalogManager.catalogResolver(catalogFeatures,
- catalogUrls.toArray(new String[0]));
+ catalogUrls.stream().toArray(URI[]::new));
} catch (Exception ex) {
entityResolver = null;
}
@@ -791,7 +791,7 @@
// Since javax.xml.catalog is unmodifiable we need to track catalog
// URLs added and create new catalog each time addCatalog is called
- private final ArrayList<String> catalogUrls = new ArrayList<String>();
+ private final ArrayList<URI> catalogUrls = new ArrayList<>();
// Cache CatalogFeatures instance for future usages.
// Resolve feature is set to "continue" value for backward compatibility.
--- a/jdk/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
5a846396a24c7aff01d6a8feaa7afc0a6369f04d jdk-9+149
71e198ef3839045e829a879af1d709be16ab0f88 jdk-9+150
d27bab22ff62823902d93d1d35ca397cfd50d059 jdk-9+151
+a20f2cf90762673e1bc4980fd6597e70a2578045 jdk-9+152
+1c4411322327aea3f91011ec3977a12a05b09629 jdk-9+153
--- a/jdk/make/data/fontconfig/solaris.fontconfig.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/make/data/fontconfig/solaris.fontconfig.properties Tue Jan 24 00:30:23 2017 +0100
@@ -436,15 +436,15 @@
filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arial.ttf
filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/ariali.ttf
-filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialb.ttf
+filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbd.ttf
filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbi.ttf
filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cour.ttf
filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/couri.ttf
-filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courb.ttf
+filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbd.ttf
filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbi.ttf
filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/times.ttf
filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesi.ttf
-filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesb.ttf
+filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbd.ttf
filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbi.ttf
filename.-monotype-angsana_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsa.ttf
--- a/jdk/make/lib/Awt2dLibraries.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/make/lib/Awt2dLibraries.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -222,6 +222,8 @@
# applies to debug builds.
ifeq ($(TOOLCHAIN_TYPE), gcc)
BUILD_LIBAWT_debug_mem.c_CFLAGS := -w
+ # This option improves performance of MaskFill in Java2D by 20% for some gcc
+ LIBAWT_CFLAGS += -fgcse-after-reload
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
--- a/jdk/src/java.base/share/classes/java/io/File.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/io/File.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, 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
@@ -1962,6 +1962,9 @@
name = sb.toString();
}
+ // Normalize the path component
+ name = fs.normalize(name);
+
File f = new File(dir, name);
if (!name.equals(f.getName()) || f.isInvalid()) {
if (System.getSecurityManager() != null)
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, 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
@@ -2477,7 +2477,7 @@
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * (<code>'\u002f'</code>), then the absolute name of the resource is the
* portion of the {@code name} following the {@code '/'}.
*
* <li> Otherwise, the absolute name is of the following form:
@@ -2488,7 +2488,7 @@
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
- * (<tt>'\u002e'</tt>).
+ * (<code>'\u002e'</code>).
*
* </ul>
*
@@ -2570,7 +2570,7 @@
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
- * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * (<code>'\u002f'</code>), then the absolute name of the resource is the
* portion of the {@code name} following the {@code '/'}.
*
* <li> Otherwise, the absolute name is of the following form:
@@ -2581,7 +2581,7 @@
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
- * (<tt>'\u002e'</tt>).
+ * (<code>'\u002e'</code>).
*
* </ul>
*
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -70,34 +70,34 @@
/**
* A class loader is an object that is responsible for loading classes. The
- * class <tt>ClassLoader</tt> is an abstract class. Given the <a
+ * class {@code ClassLoader} is an abstract class. Given the <a
* href="#name">binary name</a> of a class, a class loader should attempt to
* locate or generate data that constitutes a definition for the class. A
* typical strategy is to transform the name into a file name and then read a
* "class file" of that name from a file system.
*
- * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
- * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
+ * <p> Every {@link java.lang.Class Class} object contains a {@link
+ * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
* it.
*
- * <p> <tt>Class</tt> objects for array classes are not created by class
+ * <p> {@code Class} objects for array classes are not created by class
* loaders, but are created automatically as required by the Java runtime.
* The class loader for an array class, as returned by {@link
* Class#getClassLoader()} is the same as the class loader for its element
* type; if the element type is a primitive type, then the array class has no
* class loader.
*
- * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
+ * <p> Applications implement subclasses of {@code ClassLoader} in order to
* extend the manner in which the Java virtual machine dynamically loads
* classes.
*
* <p> Class loaders may typically be used by security managers to indicate
* security domains.
*
- * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
- * classes and resources. Each instance of <tt>ClassLoader</tt> has an
+ * <p> The {@code ClassLoader} class uses a delegation model to search for
+ * classes and resources. Each instance of {@code ClassLoader} has an
* associated parent class loader. When requested to find a class or
- * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
+ * resource, a {@code ClassLoader} instance will delegate the search for the
* class or resource to its parent class loader before attempting to find the
* class or resource itself.
*
@@ -105,15 +105,15 @@
* <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
* loaders and are required to register themselves at their class initialization
* time by invoking the {@link
- * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
- * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
+ * #registerAsParallelCapable ClassLoader.registerAsParallelCapable}
+ * method. Note that the {@code ClassLoader} class is registered as parallel
* capable by default. However, its subclasses still need to register themselves
* if they are parallel capable.
* In environments in which the delegation model is not strictly
* hierarchical, class loaders need to be parallel capable, otherwise class
* loading can lead to deadlocks because the loader lock is held for the
* duration of the class loading process (see {@link #loadClass
- * <tt>loadClass</tt>} methods).
+ * loadClass} methods).
*
* <h3> <a name="builtinLoaders">Run-time Built-in Class Loaders</a></h3>
*
@@ -143,13 +143,13 @@
* However, some classes may not originate from a file; they may originate
* from other sources, such as the network, or they could be constructed by an
* application. The method {@link #defineClass(String, byte[], int, int)
- * <tt>defineClass</tt>} converts an array of bytes into an instance of class
- * <tt>Class</tt>. Instances of this newly defined class can be created using
- * {@link Class#newInstance <tt>Class.newInstance</tt>}.
+ * defineClass} converts an array of bytes into an instance of class
+ * {@code Class}. Instances of this newly defined class can be created using
+ * {@link Class#newInstance Class.newInstance}.
*
* <p> The methods and constructors of objects created by a class loader may
* reference other classes. To determine the class(es) referred to, the Java
- * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
+ * virtual machine invokes the {@link #loadClass loadClass} method of
* the class loader that originally created the class.
*
* <p> For example, an application could create a network class loader to
@@ -162,9 +162,9 @@
* </pre></blockquote>
*
* <p> The network class loader subclass must define the methods {@link
- * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
+ * #findClass findClass} and {@code loadClassData} to load a class
* from the network. Once it has downloaded the bytes that make up the class,
- * it should use the method {@link #defineClass <tt>defineClass</tt>} to
+ * it should use the method {@link #defineClass defineClass} to
* create a class instance. A sample implementation is:
*
* <blockquote><pre>
@@ -392,7 +392,7 @@
*
* <p> If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * checkCreateClassLoader} method is invoked. This may result in
* a security exception. </p>
*
* @param parent
@@ -400,7 +400,7 @@
*
* @throws SecurityException
* If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * {@code checkCreateClassLoader} method doesn't allow creation
* of a new class loader.
*
* @since 1.2
@@ -410,18 +410,18 @@
}
/**
- * Creates a new class loader using the <tt>ClassLoader</tt> returned by
+ * Creates a new class loader using the {@code ClassLoader} returned by
* the method {@link #getSystemClassLoader()
- * <tt>getSystemClassLoader()</tt>} as the parent class loader.
+ * getSystemClassLoader()} as the parent class loader.
*
* <p> If there is a security manager, its {@link
* SecurityManager#checkCreateClassLoader()
- * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * checkCreateClassLoader} method is invoked. This may result in
* a security exception. </p>
*
* @throws SecurityException
* If a security manager exists and its
- * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * {@code checkCreateClassLoader} method doesn't allow creation
* of a new class loader.
*/
protected ClassLoader() {
@@ -458,13 +458,13 @@
* This method searches for classes in the same manner as the {@link
* #loadClass(String, boolean)} method. It is invoked by the Java virtual
* machine to resolve class references. Invoking this method is equivalent
- * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
- * false)</tt>}.
+ * to invoking {@link #loadClass(String, boolean) loadClass(name,
+ * false)}.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class was not found
@@ -483,8 +483,8 @@
* <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
* has already been loaded. </p></li>
*
- * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
- * on the parent class loader. If the parent is <tt>null</tt> the class
+ * <li><p> Invoke the {@link #loadClass(String) loadClass} method
+ * on the parent class loader. If the parent is {@code null} the class
* loader built-in to the virtual machine is used, instead. </p></li>
*
* <li><p> Invoke the {@link #findClass(String)} method to find the
@@ -493,23 +493,23 @@
* </ol>
*
* <p> If the class was found using the above steps, and the
- * <tt>resolve</tt> flag is true, this method will then invoke the {@link
- * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
+ * {@code resolve} flag is true, this method will then invoke the {@link
+ * #resolveClass(Class)} method on the resulting {@code Class} object.
*
- * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
+ * <p> Subclasses of {@code ClassLoader} are encouraged to override {@link
* #findClass(String)}, rather than this method. </p>
*
* <p> Unless overridden, this method synchronizes on the result of
- * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
+ * {@link #getClassLoadingLock getClassLoadingLock} method
* during the entire class loading process.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
* @param resolve
- * If <tt>true</tt> then resolve the class
+ * If {@code true} then resolve the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -606,7 +606,7 @@
* @return the lock for class loading operations
*
* @throws NullPointerException
- * If registered as parallel capable and <tt>className</tt> is null
+ * If registered as parallel capable and {@code className} is null
*
* @see #loadClass(String, boolean)
*
@@ -667,14 +667,14 @@
* Finds the class with the specified <a href="#name">binary name</a>.
* This method should be overridden by class loader implementations that
* follow the delegation model for loading classes, and will be invoked by
- * the {@link #loadClass <tt>loadClass</tt>} method after checking the
+ * the {@link #loadClass loadClass} method after checking the
* parent class loader for the requested class. The default implementation
- * throws a <tt>ClassNotFoundException</tt>.
+ * throws a {@code ClassNotFoundException}.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The resulting <tt>Class</tt> object
+ * @return The resulting {@code Class} object
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -722,32 +722,32 @@
/**
- * Converts an array of bytes into an instance of class <tt>Class</tt>.
- * Before the <tt>Class</tt> can be used it must be resolved. This method
+ * Converts an array of bytes into an instance of class {@code Class}.
+ * Before the {@code Class} can be used it must be resolved. This method
* is deprecated in favor of the version that takes a <a
* href="#name">binary name</a> as its first argument, and is more secure.
*
* @param b
* The bytes that make up the class data. The bytes in positions
- * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * {@code off} through {@code off+len-1} should have the format
* of a valid class file as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
*
* @param off
- * The start offset in <tt>b</tt> of the class data
+ * The start offset in {@code b} of the class data
*
* @param len
* The length of the class data
*
- * @return The <tt>Class</tt> object that was created from the specified
+ * @return The {@code Class} object that was created from the specified
* class data
*
* @throws ClassFormatError
* If the data did not contain a valid class
*
* @throws IndexOutOfBoundsException
- * If either <tt>off</tt> or <tt>len</tt> is negative, or if
- * <tt>off+len</tt> is greater than <tt>b.length</tt>.
+ * If either {@code off} or {@code len} is negative, or if
+ * {@code off+len} is greater than {@code b.length}.
*
* @throws SecurityException
* If an attempt is made to add this class to a package that
@@ -994,11 +994,11 @@
* #defineClass(String, byte[], int, int, ProtectionDomain)}.
*
* <p> An invocation of this method of the form
- * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
- * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
+ * <i>cl</i>{@code .defineClass(}<i>name</i>{@code ,}
+ * <i>bBuffer</i>{@code ,} <i>pd</i>{@code )} yields exactly the same
* result as the statements
*
- *<p> <tt>
+ *<p> <code>
* ...<br>
* byte[] temp = new byte[bBuffer.{@link
* java.nio.ByteBuffer#remaining remaining}()];<br>
@@ -1007,16 +1007,16 @@
* return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
* cl.defineClass}(name, temp, 0,
* temp.length, pd);<br>
- * </tt></p>
+ * </code></p>
*
* @param name
* The expected <a href="#name">binary name</a>. of the class, or
- * <tt>null</tt> if not known
+ * {@code null} if not known
*
* @param b
* The bytes that make up the class data. The bytes from positions
- * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
- * </tt> should have the format of a valid class file as defined by
+ * {@code b.position()} through {@code b.position() + b.limit() -1
+ * } should have the format of a valid class file as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
*
* @param protectionDomain
@@ -1158,7 +1158,7 @@
/**
* Links the specified class. This (misleadingly named) method may be
- * used by a class loader to link a class. If the class <tt>c</tt> has
+ * used by a class loader to link a class. If the class {@code c} has
* already been linked, then this method simply returns. Otherwise, the
* class is linked as described in the "Execution" chapter of
* <cite>The Java™ Language Specification</cite>.
@@ -1167,7 +1167,7 @@
* The class to link
*
* @throws NullPointerException
- * If <tt>c</tt> is <tt>null</tt>.
+ * If {@code c} is {@code null}.
*
* @see #defineClass(String, byte[], int, int)
*/
@@ -1182,16 +1182,16 @@
* loading it if necessary.
*
* <p> This method loads the class through the system class loader (see
- * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
- * might have more than one <tt>ClassLoader</tt> associated with it.
- * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
+ * {@link #getSystemClassLoader()}). The {@code Class} object returned
+ * might have more than one {@code ClassLoader} associated with it.
+ * Subclasses of {@code ClassLoader} need not usually invoke this method,
* because most class loaders need to override just {@link
* #findClass(String)}. </p>
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The <tt>Class</tt> object for the specified <tt>name</tt>
+ * @return The {@code Class} object for the specified {@code name}
*
* @throws ClassNotFoundException
* If the class could not be found
@@ -1222,12 +1222,12 @@
* Returns the class with the given <a href="#name">binary name</a> if this
* loader has been recorded by the Java virtual machine as an initiating
* loader of a class with that <a href="#name">binary name</a>. Otherwise
- * <tt>null</tt> is returned.
+ * {@code null} is returned.
*
* @param name
* The <a href="#name">binary name</a> of the class
*
- * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
+ * @return The {@code Class} object, or {@code null} if the class has
* not been loaded
*
* @since 1.1
@@ -1245,7 +1245,7 @@
* class.
*
* @param c
- * The <tt>Class</tt> object
+ * The {@code Class} object
*
* @param signers
* The signers for the class
@@ -1306,11 +1306,11 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
+ * <p> The name of a resource is a '{@code /}'-separated path name that
* identifies the resource.
*
* <p> This method will first search the parent class loader for the
- * resource; if the parent is <tt>null</tt> the path of the class loader
+ * resource; if the parent is {@code null} the path of the class loader
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
*
@@ -1362,7 +1362,7 @@
* (images, audio, text, etc) that can be accessed by class code in a way
* that is independent of the location of the code.
*
- * <p> The name of a resource is a <tt>/</tt>-separated path name that
+ * <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
* <p> The delegation order for searching is described in the documentation
@@ -1389,7 +1389,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in package that is not opened unconditionally,
@@ -1505,7 +1505,7 @@
}
/**
- * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
+ * Returns an enumeration of {@link java.net.URL URL} objects
* representing all the resources with the given name. Class loader
* implementations should override this method to specify where to load
* resources from.
@@ -1520,7 +1520,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in a package that is not opened unconditionally,
@@ -1594,7 +1594,7 @@
* @param name
* The resource name
*
- * @return A {@link java.net.URL <tt>URL</tt>} to the resource; {@code
+ * @return A {@link java.net.URL URL} to the resource; {@code
* null} if the resource could not be found, a URL could not be
* constructed to locate the resource, the resource is in a package
* that is not opened unconditionally or access to the resource is
@@ -1609,8 +1609,8 @@
/**
* Finds all resources of the specified name from the search path used to
* load classes. The resources thus found are returned as an
- * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
- * java.net.URL <tt>URL</tt>} objects.
+ * {@link java.util.Enumeration Enumeration} of {@link
+ * java.net.URL URL} objects.
*
* <p> The search order is described in the documentation for {@link
* #getSystemResource(String)}. </p>
@@ -1625,7 +1625,7 @@
* @param name
* The resource name
*
- * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * @return An enumeration of {@link java.net.URL URL} objects for
* the resource. If no resources could be found, the enumeration
* will be empty. Resources for which a {@code URL} cannot be
* constructed, are in a package that is not opened unconditionally,
@@ -1714,11 +1714,11 @@
/**
* Returns the parent class loader for delegation. Some implementations may
- * use <tt>null</tt> to represent the bootstrap class loader. This method
- * will return <tt>null</tt> in such implementations if this class loader's
+ * use {@code null} to represent the bootstrap class loader. This method
+ * will return {@code null} in such implementations if this class loader's
* parent is the bootstrap class loader.
*
- * @return The parent <tt>ClassLoader</tt>
+ * @return The parent {@code ClassLoader}
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader
@@ -1785,7 +1785,7 @@
/**
* Returns the system class loader for delegation. This is the default
- * delegation parent for new <tt>ClassLoader</tt> instances, and is
+ * delegation parent for new {@code ClassLoader} instances, and is
* typically the class loader used to start the application.
*
* <p> This method is first invoked early in the runtime's startup
@@ -1797,12 +1797,12 @@
* <p> The default system class loader is an implementation-dependent
* instance of this class.
*
- * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
+ * <p> If the system property "{@code java.system.class.loader}" is defined
* when this method is first invoked then the value of that property is
* taken to be the name of a class that will be returned as the system
* class loader. The class is loaded using the default system class loader
* and must define a public constructor that takes a single parameter of
- * type <tt>ClassLoader</tt> which is used as the delegation parent. An
+ * type {@code ClassLoader} which is used as the delegation parent. An
* instance is then created using this constructor with the default system
* class loader as the parameter. The resulting class loader is defined
* to be the system class loader. During construction, the class loader
@@ -1825,7 +1825,7 @@
* the application module path then the class path defaults to
* the current working directory.
*
- * @return The system <tt>ClassLoader</tt> for delegation
+ * @return The system {@code ClassLoader} for delegation
*
* @throws SecurityException
* If a security manager is present, and the caller's class loader
@@ -1835,11 +1835,11 @@
*
* @throws IllegalStateException
* If invoked recursively during the construction of the class
- * loader specified by the "<tt>java.system.class.loader</tt>"
+ * loader specified by the "{@code java.system.class.loader}"
* property.
*
* @throws Error
- * If the system property "<tt>java.system.class.loader</tt>"
+ * If the system property "{@code java.system.class.loader}"
* is defined but the named class could not be loaded, the
* provider class does not define the required constructor, or an
* exception is thrown by that constructor when it is invoked. The
@@ -2249,9 +2249,9 @@
/**
* Returns the absolute path name of a native library. The VM invokes this
* method to locate the native libraries that belong to classes loaded with
- * this class loader. If this method returns <tt>null</tt>, the VM
+ * this class loader. If this method returns {@code null}, the VM
* searches the library along the path specified as the
- * "<tt>java.library.path</tt>" property.
+ * "{@code java.library.path}" property.
*
* @param libname
* The library name
@@ -2270,12 +2270,12 @@
/**
* The inner class NativeLibrary denotes a loaded native library instance.
* Every classloader contains a vector of loaded native libraries in the
- * private field <tt>nativeLibraries</tt>. The native libraries loaded
- * into the system are entered into the <tt>systemNativeLibraries</tt>
+ * private field {@code nativeLibraries}. The native libraries loaded
+ * into the system are entered into the {@code systemNativeLibraries}
* vector.
*
* <p> Every native library requires a particular version of JNI. This is
- * denoted by the private <tt>jniVersion</tt> field. This field is set by
+ * denoted by the private {@code jniVersion} field. This field is set by
* the VM when it loads the library, and used by the VM to pass the correct
* version of JNI to the native methods. </p>
*
@@ -2592,8 +2592,8 @@
* #setClassAssertionStatus(String, boolean)}.
*
* @param enabled
- * <tt>true</tt> if classes loaded by this class loader will
- * henceforth have assertions enabled by default, <tt>false</tt>
+ * {@code true} if classes loaded by this class loader will
+ * henceforth have assertions enabled by default, {@code false}
* if they will have assertions disabled by default.
*
* @since 1.4
@@ -2614,16 +2614,16 @@
* any of its "subpackages".
*
* <p> A subpackage of a package named p is any package whose name begins
- * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
- * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
- * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
+ * with "{@code p.}". For example, {@code javax.swing.text} is a
+ * subpackage of {@code javax.swing}, and both {@code java.util} and
+ * {@code java.lang.reflect} are subpackages of {@code java}.
*
* <p> In the event that multiple package defaults apply to a given class,
* the package default pertaining to the most specific package takes
- * precedence over the others. For example, if <tt>javax.lang</tt> and
- * <tt>javax.lang.reflect</tt> both have package defaults associated with
+ * precedence over the others. For example, if {@code javax.lang} and
+ * {@code javax.lang.reflect} both have package defaults associated with
* them, the latter package default applies to classes in
- * <tt>javax.lang.reflect</tt>.
+ * {@code javax.lang.reflect}.
*
* <p> Package defaults take precedence over the class loader's default
* assertion status, and may be overridden on a per-class basis by invoking
@@ -2631,15 +2631,15 @@
*
* @param packageName
* The name of the package whose package default assertion status
- * is to be set. A <tt>null</tt> value indicates the unnamed
+ * is to be set. A {@code null} value indicates the unnamed
* package that is "current"
* (see section 7.4.2 of
* <cite>The Java™ Language Specification</cite>.)
*
* @param enabled
- * <tt>true</tt> if classes loaded by this classloader and
+ * {@code true} if classes loaded by this classloader and
* belonging to the named package or any of its subpackages will
- * have assertions enabled by default, <tt>false</tt> if they will
+ * have assertions enabled by default, {@code false} if they will
* have assertions disabled by default.
*
* @since 1.4
@@ -2670,8 +2670,8 @@
* assertion status is to be set.
*
* @param enabled
- * <tt>true</tt> if the named class is to have assertions
- * enabled when (and if) it is initialized, <tt>false</tt> if the
+ * {@code true} if the named class is to have assertions
+ * enabled when (and if) it is initialized, {@code false} if the
* class is to have assertions disabled.
*
* @since 1.4
@@ -2687,7 +2687,7 @@
/**
* Sets the default assertion status for this class loader to
- * <tt>false</tt> and discards any package defaults or class assertion
+ * {@code false} and discards any package defaults or class assertion
* status settings associated with the class loader. This method is
* provided so that class loaders can be made to ignore any command line or
* persistent assertion status settings and "start with a clean slate."
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Tue Jan 24 00:30:23 2017 +0100
@@ -30,8 +30,10 @@
import java.io.OutputStream;
import java.security.PrivilegedAction;
import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Date;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Objects;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
@@ -231,7 +233,7 @@
*/
protected boolean allowUserInteraction = defaultAllowUserInteraction;
- private static boolean defaultUseCaches = true;
+ private static volatile boolean defaultUseCaches = true;
/**
* If {@code true}, the protocol is allowed to use caching
@@ -243,12 +245,18 @@
* <p>
* Its default value is the value given in the last invocation of the
* {@code setDefaultUseCaches} method.
+ * <p>
+ * The default setting may be overridden per protocol with
+ * {@link #setDefaultUseCaches(String,boolean)}.
*
* @see java.net.URLConnection#setUseCaches(boolean)
* @see java.net.URLConnection#getUseCaches()
* @see java.net.URLConnection#setDefaultUseCaches(boolean)
*/
- protected boolean useCaches = defaultUseCaches;
+ protected boolean useCaches;
+
+ private static final ConcurrentHashMap<String,Boolean> defaultCaching =
+ new ConcurrentHashMap<>();
/**
* Some protocols support skipping the fetching of the object unless
@@ -460,6 +468,11 @@
*/
protected URLConnection(URL url) {
this.url = url;
+ if (url == null) {
+ this.useCaches = defaultUseCaches;
+ } else {
+ this.useCaches = getDefaultUseCaches(url.getProtocol());
+ }
}
/**
@@ -981,7 +994,8 @@
* is true, the connection is allowed to use whatever caches it can.
* If false, caches are to be ignored.
* The default value comes from DefaultUseCaches, which defaults to
- * true.
+ * true. A default value can also be set per-protocol using
+ * {@link #setDefaultUseCaches(String,boolean)}.
*
* @param usecaches a {@code boolean} indicating whether
* or not to allow caching
@@ -1032,9 +1046,10 @@
* Returns the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
* <p>
- * Ths default is "sticky", being a part of the static state of all
+ * This default is "sticky", being a part of the static state of all
* URLConnections. This flag applies to the next, and all following
- * URLConnections that are created.
+ * URLConnections that are created. This default value can be over-ridden
+ * per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @return the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
@@ -1046,7 +1061,8 @@
/**
* Sets the default value of the {@code useCaches} field to the
- * specified value.
+ * specified value. This default value can be over-ridden
+ * per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @param defaultusecaches the new value.
* @see #getDefaultUseCaches()
@@ -1055,6 +1071,43 @@
defaultUseCaches = defaultusecaches;
}
+ /**
+ * Sets the default value of the {@code useCaches} field for the named
+ * protocol to the given value. This value overrides any default setting
+ * set by {@link #setDefaultUseCaches(boolean)} for the given protocol.
+ * Successive calls to this method change the setting and affect the
+ * default value for all future connections of that protocol. The protocol
+ * name is case insensitive.
+ *
+ * @param protocol the protocol to set the default for
+ * @param defaultVal whether caching is enabled by default for the given protocol
+ * @since 9
+ */
+ public static void setDefaultUseCaches(String protocol, boolean defaultVal) {
+ protocol = protocol.toLowerCase(Locale.US);
+ defaultCaching.put(protocol, defaultVal);
+ }
+
+ /**
+ * Returns the default value of the {@code useCaches} flag for the given protocol. If
+ * {@link #setDefaultUseCaches(String,boolean)} was called for the given protocol,
+ * then that value is returned. Otherwise, if {@link #setDefaultUseCaches(boolean)}
+ * was called, then that value is returned. If neither method was called,
+ * the return value is {@code true}. The protocol name is case insensitive.
+ *
+ * @param protocol the protocol whose defaultUseCaches setting is required
+ * @return the default value of the {@code useCaches} flag for the given protocol.
+ * @since 9
+ */
+ public static boolean getDefaultUseCaches(String protocol) {
+ Boolean protoDefault = defaultCaching.get(protocol.toLowerCase(Locale.US));
+ if (protoDefault != null) {
+ return protoDefault.booleanValue();
+ } else {
+ return defaultUseCaches;
+ }
+ }
+
/**
* Sets the general request property. If a property with the key already
* exists, overwrite its value with the new value.
--- a/jdk/src/java.base/share/classes/java/util/Collections.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -4354,6 +4354,11 @@
private Object readResolve() {
return EMPTY_SET;
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
/**
@@ -4786,6 +4791,10 @@
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(element);
+ }
}
/**
@@ -4848,6 +4857,10 @@
public Spliterator<E> spliterator() {
return singletonSpliterator(element);
}
+ @Override
+ public int hashCode() {
+ return 31 + Objects.hashCode(element);
+ }
}
/**
@@ -4970,6 +4983,11 @@
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(k) ^ Objects.hashCode(v);
+ }
}
// Miscellaneous
--- a/jdk/src/java.base/share/classes/java/util/Date.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/Date.java Tue Jan 24 00:30:23 2017 +0100
@@ -82,17 +82,19 @@
* well; for example, the time scale used by the satellite-based
* global positioning system (GPS) is synchronized to UTC but is
* <i>not</i> adjusted for leap seconds. An interesting source of
- * further information is the U.S. Naval Observatory, particularly
- * the Directorate of Time at:
+ * further information is the United States Naval Observatory (USNO):
* <blockquote><pre>
- * <a href="http://www.usno.navy.mil">http://www.usno.navy.mil</a>
+ * <a href="http://www.usno.navy.mil/USNO">http://www.usno.navy.mil/USNO</a>
* </pre></blockquote>
* <p>
- * and their definitions of "Systems of Time" at:
+ * and the material regarding "Systems of Time" at:
* <blockquote><pre>
* <a href="http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
* </pre></blockquote>
* <p>
+ * which has descriptions of various different time systems including
+ * UT, UT1, and UTC.
+ * <p>
* In all methods of class {@code Date} that accept or return
* year, month, date, hours, minutes, and seconds values, the
* following representations are used:
--- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
+import jdk.internal.vm.annotation.Stable;
/**
* Container class for immutable collections. Not part of the public API.
@@ -105,6 +106,11 @@
return null; // but the compiler doesn't know this
}
+ @Override
+ public Iterator<E> iterator() {
+ return Collections.emptyIterator();
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -112,9 +118,26 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST);
}
+
+ @Override
+ public boolean contains(Object o) {
+ Objects.requireNonNull(o);
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> o) {
+ return o.isEmpty(); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return 1;
+ }
}
static final class List1<E> extends AbstractImmutableList<E> {
+ @Stable
private final E e0;
List1(E e0) {
@@ -129,7 +152,6 @@
@Override
public E get(int index) {
Objects.checkIndex(index, 1);
- // assert index == 0
return e0;
}
@@ -140,10 +162,22 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST, e0);
}
+
+ @Override
+ public boolean contains(Object o) {
+ return o.equals(e0); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 + e0.hashCode();
+ }
}
static final class List2<E> extends AbstractImmutableList<E> {
+ @Stable
private final E e0;
+ @Stable
private final E e1;
List2(E e0, E e1) {
@@ -166,6 +200,17 @@
}
}
+ @Override
+ public boolean contains(Object o) {
+ return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 31 + e0.hashCode();
+ return 31 * hash + e1.hashCode();
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -176,6 +221,7 @@
}
static final class ListN<E> extends AbstractImmutableList<E> {
+ @Stable
private final E[] elements;
@SafeVarargs
@@ -200,6 +246,25 @@
return elements[index];
}
+ @Override
+ public boolean contains(Object o) {
+ for (E e : elements) {
+ if (o.equals(e)) { // implicit nullcheck of o
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ for (E e : elements) {
+ hash = 31 * hash + e.hashCode();
+ }
+ return hash;
+ }
+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@@ -238,7 +303,13 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> o) {
+ return o.isEmpty(); // implicit nullcheck of o
}
@Override
@@ -253,9 +324,15 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET);
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
static final class Set1<E> extends AbstractImmutableSet<E> {
+ @Stable
private final E e0;
Set1(E e0) {
@@ -269,7 +346,7 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ return o.equals(e0); // implicit nullcheck of o
}
@Override
@@ -284,17 +361,21 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET, e0);
}
+
+ @Override
+ public int hashCode() {
+ return e0.hashCode();
+ }
}
static final class Set2<E> extends AbstractImmutableSet<E> {
- private final E e0;
- private final E e1;
+ @Stable
+ final E e0;
+ @Stable
+ final E e1;
Set2(E e0, E e1) {
- Objects.requireNonNull(e0);
- Objects.requireNonNull(e1);
-
- if (e0.equals(e1)) {
+ if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
throw new IllegalArgumentException("duplicate element: " + e0);
}
@@ -314,7 +395,12 @@
@Override
public boolean contains(Object o) {
- return super.contains(Objects.requireNonNull(o));
+ return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+ }
+
+ @Override
+ public int hashCode() {
+ return e0.hashCode() + e1.hashCode();
}
@Override
@@ -358,8 +444,10 @@
* @param <E> the element type
*/
static final class SetN<E> extends AbstractImmutableSet<E> {
- private final E[] elements;
- private final int size;
+ @Stable
+ final E[] elements;
+ @Stable
+ final int size;
@SafeVarargs
@SuppressWarnings("unchecked")
@@ -368,8 +456,8 @@
elements = (E[])new Object[EXPAND_FACTOR * input.length];
for (int i = 0; i < input.length; i++) {
- E e = Objects.requireNonNull(input[i]);
- int idx = probe(e);
+ E e = input[i];
+ int idx = probe(e); // implicit nullcheck of e
if (idx >= 0) {
throw new IllegalArgumentException("duplicate element: " + e);
} else {
@@ -385,8 +473,7 @@
@Override
public boolean contains(Object o) {
- Objects.requireNonNull(o);
- return probe(o) >= 0;
+ return probe(o) >= 0; // implicit nullcheck of o
}
@Override
@@ -414,8 +501,21 @@
};
}
+ @Override
+ public int hashCode() {
+ int h = 0;
+ for (E e : elements) {
+ if (e != null) {
+ h += e.hashCode();
+ }
+ }
+ return h;
+ }
+
// returns index at which element is present; or if absent,
- // (-i - 1) where i is location where element should be inserted
+ // (-i - 1) where i is location where element should be inserted.
+ // Callers are relying on this method to perform an implicit nullcheck
+ // of pe
private int probe(Object pe) {
int idx = Math.floorMod(pe.hashCode() ^ SALT, elements.length);
while (true) {
@@ -481,12 +581,14 @@
@Override
public boolean containsKey(Object o) {
- return super.containsKey(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ Objects.requireNonNull(o);
+ return false;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -496,10 +598,17 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP);
}
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
}
static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
+ @Stable
private final K k0;
+ @Stable
private final V v0;
Map1(K k0, V v0) {
@@ -514,12 +623,12 @@
@Override
public boolean containsKey(Object o) {
- return super.containsKey(Objects.requireNonNull(o));
+ return o.equals(k0); // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ return o.equals(v0); // implicit nullcheck of o
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -529,6 +638,11 @@
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP, k0, v0);
}
+
+ @Override
+ public int hashCode() {
+ return k0.hashCode() ^ v0.hashCode();
+ }
}
/**
@@ -541,12 +655,13 @@
* @param <V> the value type
*/
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
- private final Object[] table; // pairs of key, value
- private final int size; // number of pairs
+ @Stable
+ final Object[] table; // pairs of key, value
+ @Stable
+ final int size; // number of pairs
MapN(Object... input) {
- Objects.requireNonNull(input);
- if ((input.length & 1) != 0) {
+ if ((input.length & 1) != 0) { // implicit nullcheck of input
throw new InternalError("length is odd");
}
size = input.length >> 1;
@@ -573,12 +688,30 @@
@Override
public boolean containsKey(Object o) {
- return probe(Objects.requireNonNull(o)) >= 0;
+ return probe(o) >= 0; // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
- return super.containsValue(Objects.requireNonNull(o));
+ for (int i = 1; i < table.length; i += 2) {
+ Object v = table[i];
+ if (v != null && o.equals(v)) { // implicit nullcheck of o
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ for (int i = 0; i < table.length; i += 2) {
+ Object k = table[i];
+ if (k != null) {
+ hash += k.hashCode() ^ table[i + 1].hashCode();
+ }
+ }
+ return hash;
}
@Override
@@ -638,7 +771,9 @@
}
// returns index at which the probe key is present; or if absent,
- // (-i - 1) where i is location where element should be inserted
+ // (-i - 1) where i is location where element should be inserted.
+ // Callers are relying on this method to perform an implicit nullcheck
+ // of pk.
private int probe(Object pk) {
int idx = Math.floorMod(pk.hashCode() ^ SALT, table.length >> 1) << 1;
while (true) {
--- a/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package java.util;
+import jdk.internal.vm.annotation.Stable;
+
/**
* An immutable container for a key and a value, suitable for use
* in creating and populating {@code Map} instances.
@@ -48,7 +50,9 @@
* @since 9
*/
final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
+ @Stable
final K key;
+ @Stable
final V value;
KeyValueHolder(K k, V v) {
--- a/jdk/src/java.base/share/classes/java/util/List.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/List.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -1027,8 +1027,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <E> List<E> of(E... elements) {
- Objects.requireNonNull(elements);
- switch (elements.length) {
+ switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.List0.instance();
case 1:
--- a/jdk/src/java.base/share/classes/java/util/Map.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/Map.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -1602,8 +1602,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
- Objects.requireNonNull(entries);
- if (entries.length == 0) {
+ if (entries.length == 0) { // implicit null check of entries
return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
return new ImmutableCollections.Map1<>(entries[0].getKey(),
--- a/jdk/src/java.base/share/classes/java/util/Set.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/classes/java/util/Set.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -689,8 +689,7 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <E> Set<E> of(E... elements) {
- Objects.requireNonNull(elements);
- switch (elements.length) {
+ switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.Set0.instance();
case 1:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2017, 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.internal.module;
+
+import java.io.PrintStream;
+import java.lang.module.Configuration;
+import java.lang.module.ResolvedModule;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import static java.util.stream.Collectors.*;
+
+/**
+ * A Builder to compute ModuleHashes from a given configuration
+ */
+public class ModuleHashesBuilder {
+ private final Configuration configuration;
+ private final Set<String> hashModuleCandidates;
+
+ /**
+ * Constructs a ModuleHashesBuilder that finds the packaged modules
+ * from the location of ModuleReference found from the given Configuration.
+ *
+ * @param config Configuration for building module hashes
+ * @param modules the candidate modules to be hashed
+ */
+ public ModuleHashesBuilder(Configuration config, Set<String> modules) {
+ this.configuration = config;
+ this.hashModuleCandidates = modules;
+ }
+
+ /**
+ * Returns a map of a module M to ModuleHashes for the modules
+ * that depend upon M directly or indirectly.
+ *
+ * The key for each entry in the returned map is a module M that has
+ * no outgoing edges to any of the candidate modules to be hashed
+ * i.e. M is a leaf node in a connected subgraph containing M and
+ * other candidate modules from the module graph filtering
+ * the outgoing edges from M to non-candidate modules.
+ */
+ public Map<String, ModuleHashes> computeHashes(Set<String> roots) {
+ // build a graph containing the the packaged modules and
+ // its transitive dependences matching --hash-modules
+ Graph.Builder<String> builder = new Graph.Builder<>();
+ Deque<ResolvedModule> deque = new ArrayDeque<>(configuration.modules());
+ Set<ResolvedModule> visited = new HashSet<>();
+ while (!deque.isEmpty()) {
+ ResolvedModule rm = deque.pop();
+ if (!visited.contains(rm)) {
+ visited.add(rm);
+ builder.addNode(rm.name());
+ for (ResolvedModule dm : rm.reads()) {
+ if (!visited.contains(dm)) {
+ deque.push(dm);
+ }
+ builder.addEdge(rm.name(), dm.name());
+ }
+ }
+ }
+
+ // each node in a transposed graph is a matching packaged module
+ // in which the hash of the modules that depend upon it is recorded
+ Graph<String> transposedGraph = builder.build().transpose();
+
+ // traverse the modules in topological order that will identify
+ // the modules to record the hashes - it is the first matching
+ // module and has not been hashed during the traversal.
+ Set<String> mods = new HashSet<>();
+ Map<String, ModuleHashes> hashes = new HashMap<>();
+ builder.build()
+ .orderedNodes()
+ .filter(mn -> roots.contains(mn) && !mods.contains(mn))
+ .forEach(mn -> {
+ // Compute hashes of the modules that depend on mn directly and
+ // indirectly excluding itself.
+ Set<String> ns = transposedGraph.dfs(mn)
+ .stream()
+ .filter(n -> !n.equals(mn) && hashModuleCandidates.contains(n))
+ .collect(toSet());
+ mods.add(mn);
+ mods.addAll(ns);
+
+ if (!ns.isEmpty()) {
+ Map<String, Path> moduleToPath = ns.stream()
+ .collect(toMap(Function.identity(), this::moduleToPath));
+ hashes.put(mn, ModuleHashes.generate(moduleToPath, "SHA-256"));
+ }
+ });
+ return hashes;
+ }
+
+ private Path moduleToPath(String name) {
+ ResolvedModule rm = configuration.findModule(name).orElseThrow(
+ () -> new InternalError("Selected module " + name + " not on module path"));
+
+ URI uri = rm.reference().location().get();
+ Path path = Paths.get(uri);
+ String fn = path.getFileName().toString();
+ if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
+ throw new UnsupportedOperationException(path + " is not a modular JAR or jmod file");
+ }
+ return path;
+ }
+
+ /*
+ * Utilty class
+ */
+ static class Graph<T> {
+ private final Set<T> nodes;
+ private final Map<T, Set<T>> edges;
+
+ public Graph(Set<T> nodes, Map<T, Set<T>> edges) {
+ this.nodes = Collections.unmodifiableSet(nodes);
+ this.edges = Collections.unmodifiableMap(edges);
+ }
+
+ public Set<T> nodes() {
+ return nodes;
+ }
+
+ public Map<T, Set<T>> edges() {
+ return edges;
+ }
+
+ public Set<T> adjacentNodes(T u) {
+ return edges.get(u);
+ }
+
+ public boolean contains(T u) {
+ return nodes.contains(u);
+ }
+
+ /**
+ * Returns nodes sorted in topological order.
+ */
+ public Stream<T> orderedNodes() {
+ TopoSorter<T> sorter = new TopoSorter<>(this);
+ return sorter.result.stream();
+ }
+
+ /**
+ * Traverse this graph and performs the given action in topological order
+ */
+ public void ordered(Consumer<T> action) {
+ TopoSorter<T> sorter = new TopoSorter<>(this);
+ sorter.ordered(action);
+ }
+
+ /**
+ * Traverses this graph and performs the given action in reverse topological order
+ */
+ public void reverse(Consumer<T> action) {
+ TopoSorter<T> sorter = new TopoSorter<>(this);
+ sorter.reverse(action);
+ }
+
+ /**
+ * Returns a transposed graph from this graph
+ */
+ public Graph<T> transpose() {
+ Builder<T> builder = new Builder<>();
+ nodes.stream().forEach(builder::addNode);
+ // reverse edges
+ edges.keySet().forEach(u -> {
+ edges.get(u).stream()
+ .forEach(v -> builder.addEdge(v, u));
+ });
+ return builder.build();
+ }
+
+ /**
+ * Returns all nodes reachable from the given root.
+ */
+ public Set<T> dfs(T root) {
+ return dfs(Set.of(root));
+ }
+
+ /**
+ * Returns all nodes reachable from the given set of roots.
+ */
+ public Set<T> dfs(Set<T> roots) {
+ Deque<T> deque = new LinkedList<>(roots);
+ Set<T> visited = new HashSet<>();
+ while (!deque.isEmpty()) {
+ T u = deque.pop();
+ if (!visited.contains(u)) {
+ visited.add(u);
+ if (contains(u)) {
+ adjacentNodes(u).stream()
+ .filter(v -> !visited.contains(v))
+ .forEach(deque::push);
+ }
+ }
+ }
+ return visited;
+ }
+
+ public void printGraph(PrintStream out) {
+ out.println("graph for " + nodes);
+ nodes.stream()
+ .forEach(u -> adjacentNodes(u).stream()
+ .forEach(v -> out.format(" %s -> %s%n", u, v)));
+ }
+
+ static class Builder<T> {
+ final Set<T> nodes = new HashSet<>();
+ final Map<T, Set<T>> edges = new HashMap<>();
+
+ public void addNode(T node) {
+ if (nodes.contains(node)) {
+ return;
+ }
+ nodes.add(node);
+ edges.computeIfAbsent(node, _e -> new HashSet<>());
+ }
+
+ public void addEdge(T u, T v) {
+ addNode(u);
+ addNode(v);
+ edges.get(u).add(v);
+ }
+
+ public Graph<T> build() {
+ return new Graph<T>(nodes, edges);
+ }
+ }
+ }
+
+ /**
+ * Topological sort
+ */
+ private static class TopoSorter<T> {
+ final Deque<T> result = new LinkedList<>();
+ final Deque<T> nodes;
+ final Graph<T> graph;
+
+ TopoSorter(Graph<T> graph) {
+ this.graph = graph;
+ this.nodes = new LinkedList<>(graph.nodes);
+ sort();
+ }
+
+ public void ordered(Consumer<T> action) {
+ result.iterator().forEachRemaining(action);
+ }
+
+ public void reverse(Consumer<T> action) {
+ result.descendingIterator().forEachRemaining(action);
+ }
+
+ private void sort() {
+ Deque<T> visited = new LinkedList<>();
+ Deque<T> done = new LinkedList<>();
+ T node;
+ while ((node = nodes.poll()) != null) {
+ if (!visited.contains(node)) {
+ visit(node, visited, done);
+ }
+ }
+ }
+
+ private void visit(T node, Deque<T> visited, Deque<T> done) {
+ if (visited.contains(node)) {
+ if (!done.contains(node)) {
+ throw new IllegalArgumentException("Cyclic detected: " +
+ node + " " + graph.edges().get(node));
+ }
+ return;
+ }
+ visited.add(node);
+ graph.edges().get(node).stream()
+ .forEach(x -> visit(x, visited, done));
+ done.add(node);
+ result.addLast(node);
+ }
+ }
+}
--- a/jdk/src/java.base/share/native/libnet/net_util.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/native/libnet/net_util.c Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -64,10 +64,10 @@
preferIPv4Stack = (*env)->CallStaticBooleanMethod(env, iCls, mid, s);
/*
- Since we have initialized and loaded the Socket library we will
- check now to whether we have IPv6 on this platform and if the
- supporting socket APIs are available
- */
+ * Since we have initialized and loaded the socket library we will
+ * check now whether we have IPv6 on this platform and if the
+ * supporting socket APIs are available
+ */
IPv6_available = IPv6_supported() & (!preferIPv4Stack);
/* check if SO_REUSEPORT is supported on this platform */
@@ -120,16 +120,16 @@
return JNI_TRUE;
}
-int getInet6Address_scopeid_set(JNIEnv *env, jobject iaObj) {
+jboolean getInet6Address_scopeid_set(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
- CHECK_NULL_RETURN(holder, -1);
+ CHECK_NULL_RETURN(holder, JNI_FALSE);
return (*env)->GetBooleanField(env, holder, ia6_scopeidsetID);
}
-int getInet6Address_scopeid(JNIEnv *env, jobject iaObj) {
+unsigned int getInet6Address_scopeid(JNIEnv *env, jobject iaObj) {
jobject holder = (*env)->GetObjectField(env, iaObj, ia6_holder6ID);
- CHECK_NULL_RETURN(holder, -1);
- return (*env)->GetIntField(env, holder, ia6_scopeidID);
+ CHECK_NULL_RETURN(holder, 0);
+ return (unsigned int)(*env)->GetIntField(env, holder, ia6_scopeidID);
}
jboolean setInet6Address_scopeid(JNIEnv *env, jobject iaObj, int scopeid) {
@@ -201,11 +201,10 @@
}
JNIEXPORT jobject JNICALL
-NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
+NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port) {
jobject iaObj;
- if (him->sa_family == AF_INET6) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- jbyte *caddr = (jbyte *)&(him6->sin6_addr);
+ if (sa->sa.sa_family == AF_INET6) {
+ jbyte *caddr = (jbyte *)&sa->sa6.sin6_addr;
if (NET_IsIPv4Mapped(caddr)) {
int address;
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
@@ -214,42 +213,35 @@
setInetAddress_addr(env, iaObj, address);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
} else {
- jint scope;
jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
CHECK_NULL_RETURN(iaObj, NULL);
- ret = setInet6Address_ipaddress(env, iaObj, (char *)&(him6->sin6_addr));
+ ret = setInet6Address_ipaddress(env, iaObj, (char *)&sa->sa6.sin6_addr);
if (ret == JNI_FALSE)
return NULL;
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
- scope = getScopeID(him);
- setInet6Address_scopeid(env, iaObj, scope);
+ setInet6Address_scopeid(env, iaObj, sa->sa6.sin6_scope_id);
}
- *port = ntohs(him6->sin6_port);
+ *port = ntohs(sa->sa6.sin6_port);
} else {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
CHECK_NULL_RETURN(iaObj, NULL);
setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
- setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
- *port = ntohs(him4->sin_port);
+ setInetAddress_addr(env, iaObj, ntohl(sa->sa4.sin_addr.s_addr));
+ *port = ntohs(sa->sa4.sin_port);
}
return iaObj;
}
-JNIEXPORT jint JNICALL
-NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
+JNIEXPORT jboolean JNICALL
+NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj)
{
- jint family = AF_INET;
-
- family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
- AF_INET : AF_INET6;
- if (him->sa_family == AF_INET6) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- jbyte *caddrNew = (jbyte *)&(him6->sin6_addr);
+ jint family = getInetAddress_family(env, iaObj) ==
+ java_net_InetAddress_IPv4 ? AF_INET : AF_INET6;
+ if (sa->sa.sa_family == AF_INET6) {
+ jbyte *caddrNew = (jbyte *)&sa->sa6.sin6_addr;
if (NET_IsIPv4Mapped(caddrNew)) {
- int addrNew;
- int addrCur;
+ int addrNew, addrCur;
if (family == AF_INET6) {
return JNI_FALSE;
}
@@ -262,26 +254,24 @@
}
} else {
jbyte caddrCur[16];
- int scope;
-
if (family == AF_INET) {
return JNI_FALSE;
}
- scope = getInet6Address_scopeid(env, iaObj);
getInet6Address_ipaddress(env, iaObj, (char *)caddrCur);
- if (NET_IsEqual(caddrNew, caddrCur) && cmpScopeID(scope, him)) {
+ if (NET_IsEqual(caddrNew, caddrCur) &&
+ sa->sa6.sin6_scope_id == getInet6Address_scopeid(env, iaObj))
+ {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}
} else {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
int addrNew, addrCur;
if (family != AF_INET) {
return JNI_FALSE;
}
- addrNew = ntohl(him4->sin_addr.s_addr);
+ addrNew = ntohl(sa->sa4.sin_addr.s_addr);
addrCur = getInetAddress_addr(env, iaObj);
if (addrNew == addrCur) {
return JNI_TRUE;
@@ -291,6 +281,15 @@
}
}
+JNIEXPORT jint JNICALL
+NET_GetPortFromSockaddr(SOCKETADDRESS *sa) {
+ if (sa->sa.sa_family == AF_INET6) {
+ return ntohs(sa->sa6.sin6_port);
+ } else {
+ return ntohs(sa->sa4.sin_port);
+ }
+}
+
unsigned short
in_cksum(unsigned short *addr, int len) {
int nleft = len;
--- a/jdk/src/java.base/share/native/libnet/net_util.h Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/share/native/libnet/net_util.h Tue Jan 24 00:30:23 2017 +0100
@@ -63,8 +63,8 @@
*/
extern jobject getInet6Address_scopeifname(JNIEnv *env, jobject ia6Obj);
extern jboolean setInet6Address_scopeifname(JNIEnv *env, jobject ia6Obj, jobject scopeifname);
-extern int getInet6Address_scopeid_set(JNIEnv *env, jobject ia6Obj);
-extern int getInet6Address_scopeid(JNIEnv *env, jobject ia6Obj);
+extern jboolean getInet6Address_scopeid_set(JNIEnv *env, jobject ia6Obj);
+extern unsigned int getInet6Address_scopeid(JNIEnv *env, jobject ia6Obj);
extern jboolean setInet6Address_scopeid(JNIEnv *env, jobject ia6Obj, int scopeid);
extern jboolean getInet6Address_ipaddress(JNIEnv *env, jobject ia6Obj, char *dest);
extern jboolean setInet6Address_ipaddress(JNIEnv *env, jobject ia6Obj, char *address);
@@ -132,24 +132,41 @@
JNIEXPORT jint JNICALL reuseport_available();
+/**
+ * This function will fill a SOCKETADDRESS structure from an InetAddress
+ * object.
+ *
+ * The parameter 'sa' must point to valid storage of size
+ * 'sizeof(SOCKETADDRESS)'.
+ *
+ * The parameter 'len' is a pointer to an int and is used for returning
+ * the actual sockaddr length, e.g. 'sizeof(struct sockaddr_in)' or
+ * 'sizeof(struct sockaddr_in6)'.
+ *
+ * If the type of the InetAddress object is IPv6, the function will fill a
+ * sockaddr_in6 structure. IPv6 must be available in that case, otherwise an
+ * exception is thrown.
+ * In the case of an IPv4 InetAddress, when IPv6 is available and
+ * v4MappedAddress is TRUE, this method will fill a sockaddr_in6 structure
+ * containing an IPv4 mapped IPv6 address. Otherwise a sockaddr_in
+ * structure will be filled.
+ */
JNIEXPORT int JNICALL
NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
- struct sockaddr *him, int *len,
+ SOCKETADDRESS *sa, int *len,
jboolean v4MappedAddress);
JNIEXPORT jobject JNICALL
-NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
+NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port);
void platformInit();
void parseExclusiveBindProperty(JNIEnv *env);
-void NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
+JNIEXPORT jint JNICALL NET_GetPortFromSockaddr(SOCKETADDRESS *sa);
-JNIEXPORT jint JNICALL NET_GetPortFromSockaddr(struct sockaddr *him);
-
-JNIEXPORT jint JNICALL
-NET_SockaddrEqualsInetAddress(JNIEnv *env,struct sockaddr *him, jobject iaObj);
+JNIEXPORT jboolean JNICALL
+NET_SockaddrEqualsInetAddress(JNIEnv *env, SOCKETADDRESS *sa, jobject iaObj);
int NET_IsIPv4Mapped(jbyte* caddr);
@@ -172,7 +189,7 @@
NET_SetSockOpt(int fd, int level, int opt, const void *arg, int len);
JNIEXPORT int JNICALL
-NET_Bind(int fd, struct sockaddr *him, int len);
+NET_Bind(int fd, SOCKETADDRESS *sa, int len);
JNIEXPORT int JNICALL
NET_MapSocketOption(jint cmd, int *level, int *optname);
@@ -183,10 +200,6 @@
JNIEXPORT jint JNICALL
NET_EnableFastTcpLoopback(int fd);
-int getScopeID(struct sockaddr *);
-
-int cmpScopeID(unsigned int, struct sockaddr *);
-
unsigned short in_cksum(unsigned short *addr, int len);
jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
--- a/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -211,7 +211,8 @@
{
int port;
int index = (family == AF_INET) ? i++ : j++;
- jobject o = NET_SockaddrToInetAddress(env, iter->ifa_addr, &port);
+ jobject o = NET_SockaddrToInetAddress(env,
+ (SOCKETADDRESS *)iter->ifa_addr, &port);
if (!o) {
freeifaddrs(ifa);
if (!(*env)->ExceptionCheck(env))
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -791,7 +791,7 @@
int sock;
sock = openSocket(env, AF_INET);
- if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+ if (sock < 0) {
return NULL;
}
@@ -809,7 +809,7 @@
// so we have to call ipv6_available()
if (ipv6_available()) {
sock = openSocket(env, AF_INET6);
- if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+ if (sock < 0) {
freeif(ifs);
return NULL;
}
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -99,7 +99,7 @@
CHECK_NULL_RETURN(i_class, NULL);
}
- return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
+ return (*env)->NewObject(env, i_class, i_ctrID, i);
}
/*
@@ -118,10 +118,9 @@
CHECK_NULL_RETURN(b_class, NULL);
}
- return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
+ return (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b != 0));
}
-
/*
* Returns the fd for a PlainDatagramSocketImpl or -1
* if closed.
@@ -134,7 +133,6 @@
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
-
/*
* Class: java_net_PlainDatagramSocketImpl
* Method: init
@@ -166,7 +164,6 @@
initInetAddressIDs(env);
JNU_CHECK_EXCEPTION(env);
Java_java_net_NetworkInterface_init(env, 0);
-
}
/*
@@ -176,13 +173,13 @@
*/
JNIEXPORT void JNICALL
Java_java_net_PlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
- jint localport, jobject iaObj) {
+ jint localport, jobject iaObj) {
/* fdObj is the FileDescriptor field on this */
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
/* fd is an int field on fdObj */
int fd;
int len = 0;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
socklen_t slen = sizeof(SOCKETADDRESS);
if (IS_NULL(fdObj)) {
@@ -199,12 +196,13 @@
}
/* bind */
- if (NET_InetAddressToSockaddr(env, iaObj, localport, &him.sa, &len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa, &len,
+ JNI_TRUE) != 0) {
return;
}
- setDefaultScopeID(env, &him.sa);
+ setDefaultScopeID(env, &sa.sa);
- if (NET_Bind(fd, &him.sa, len) < 0) {
+ if (NET_Bind(fd, &sa, len) < 0) {
if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
errno == EPERM || errno == EACCES) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
@@ -221,13 +219,13 @@
/* Now that we're a connected socket, let's extract the port number
* that the system chose for us and store it in the Socket object.
*/
- if (getsockname(fd, &him.sa, &slen) == -1) {
+ if (getsockname(fd, &sa.sa, &slen) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return;
}
- localport = NET_GetPortFromSockaddr(&him.sa);
+ localport = NET_GetPortFromSockaddr(&sa);
(*env)->SetIntField(env, this, pdsi_localPortID, localport);
} else {
@@ -263,7 +261,8 @@
return;
}
- if (NET_InetAddressToSockaddr(env, address, port, &rmtaddr.sa, &len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, address, port, &rmtaddr, &len,
+ JNI_TRUE) != 0) {
return;
}
@@ -290,6 +289,9 @@
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
SOCKETADDRESS addr;
socklen_t len;
+#if defined(__linux__)
+ int localPort = 0;
+#endif
#endif
if (IS_NULL(fdObj)) {
@@ -298,32 +300,31 @@
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
- memset(&addr, 0, sizeof(addr));
- if (ipv6_available()) {
- addr.sa6.sin6_family = AF_UNSPEC;
- len = sizeof(struct sockaddr_in6);
- } else {
- addr.sa4.sin_family = AF_UNSPEC;
- len = sizeof(struct sockaddr_in);
- }
- NET_Connect(fd, &addr.sa, len);
+ memset(&addr, 0, sizeof(addr));
+ if (ipv6_available()) {
+ addr.sa6.sin6_family = AF_UNSPEC;
+ len = sizeof(struct sockaddr_in6);
+ } else {
+ addr.sa4.sin_family = AF_UNSPEC;
+ len = sizeof(struct sockaddr_in);
+ }
+ NET_Connect(fd, &addr.sa, len);
-#ifdef __linux__
- int localPort = 0;
- if (getsockname(fd, &addr.sa, &len) == -1)
- return;
+#if defined(__linux__)
+ if (getsockname(fd, &addr.sa, &len) == -1)
+ return;
- localPort = NET_GetPortFromSockaddr(&addr.sa);
- if (localPort == 0) {
- localPort = (*env)->GetIntField(env, this, pdsi_localPortID);
- if (addr.sa.sa_family == AF_INET6) {
- addr.sa6.sin6_port = htons(localPort);
- } else {
- addr.sa4.sin_port = htons(localPort);
- }
+ localPort = NET_GetPortFromSockaddr(&addr);
+ if (localPort == 0) {
+ localPort = (*env)->GetIntField(env, this, pdsi_localPortID);
+ if (addr.sa.sa_family == AF_INET6) {
+ addr.sa6.sin6_port = htons(localPort);
+ } else {
+ addr.sa4.sin_port = htons(localPort);
+ }
- NET_Bind(fd, &addr.sa, len);
- }
+ NET_Bind(fd, &addr, len);
+ }
#endif
#else
@@ -355,8 +356,9 @@
/* The fdObj'fd */
jint fd;
- SOCKETADDRESS rmtaddr, *rmtaddrP = &rmtaddr;
- int len;
+ SOCKETADDRESS rmtaddr;
+ struct sockaddr *rmtaddrP = 0;
+ int len = 0;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -382,15 +384,14 @@
packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
- if (connected) {
- /* arg to NET_Sendto () null in this case */
- len = 0;
- rmtaddrP = 0;
- } else {
+ // arg to NET_Sendto() null, if connected
+ if (!connected) {
packetPort = (*env)->GetIntField(env, packet, dp_portID);
- if (NET_InetAddressToSockaddr(env, packetAddress, packetPort, &rmtaddr.sa, &len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, packetAddress, packetPort, &rmtaddr,
+ &len, JNI_TRUE) != 0) {
return;
}
+ rmtaddrP = &rmtaddr.sa;
}
setDefaultScopeID(env, &rmtaddr.sa);
@@ -427,7 +428,7 @@
(*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
(jbyte *)fullPacket);
if (trafficClass != 0 && ipv6_available()) {
- NET_SetTrafficClass(&rmtaddr.sa, trafficClass);
+ NET_SetTrafficClass(&rmtaddr, trafficClass);
}
/*
@@ -437,8 +438,7 @@
* ECONNREFUSED indicating that an ICMP port unreachable has
* received.
*/
- ret = NET_SendTo(fd, fullPacket, packetBufferLen, 0,
- (struct sockaddr *)rmtaddrP, len);
+ ret = NET_SendTo(fd, fullPacket, packetBufferLen, 0, rmtaddrP, len);
if (ret < 0) {
if (errno == ECONNREFUSED) {
@@ -510,7 +510,7 @@
#ifdef __solaris__
if (errno == ECONNREFUSED) {
int orig_errno = errno;
- (void) recv(fd, buf, 1, 0);
+ recv(fd, buf, 1, 0);
errno = orig_errno;
}
#endif
@@ -528,7 +528,7 @@
return 0;
}
- iaObj = NET_SockaddrToInetAddress(env, &rmtaddr.sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
AF_INET : AF_INET6;
if (family == AF_INET) { /* this API can't handle IPV6 addresses */
@@ -676,18 +676,18 @@
*/
packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, &rmtaddr.sa, packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &rmtaddr, packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, &rmtaddr.sa, &port);
+ packetAddress = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
/* stuff the new Inetaddress in the packet */
(*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
} else {
/* only get the new port number */
- port = NET_GetPortFromSockaddr(&rmtaddr.sa);
+ port = NET_GetPortFromSockaddr(&rmtaddr);
}
/* and fill in the data, remote address/port and such */
(*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
@@ -857,18 +857,19 @@
*/
packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, &rmtaddr.sa, packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &rmtaddr,
+ packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, &rmtaddr.sa, &port);
+ packetAddress = NET_SockaddrToInetAddress(env, &rmtaddr, &port);
/* stuff the new Inetaddress in the packet */
(*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
} else {
/* only get the new port number */
- port = NET_GetPortFromSockaddr(&rmtaddr.sa);
+ port = NET_GetPortFromSockaddr(&rmtaddr);
}
/* and fill in the data, remote address/port and such */
(*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
@@ -1040,6 +1041,7 @@
/*
* We need an ipv4 address here
*/
+ in.s_addr = 0;
for (i = 0; i < len; i++) {
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
if (getInetAddress_family(env, addr) == java_net_InetAddress_IPv4) {
@@ -1049,7 +1051,7 @@
}
if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (const char*)&in, sizeof(in)) < 0) {
+ (const char *)&in, sizeof(in)) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
}
@@ -1670,17 +1672,17 @@
*/
if (opt == java_net_SocketOptions_SO_BINDADDR) {
/* find out local IP address */
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
socklen_t len = sizeof(SOCKETADDRESS);
int port;
jobject iaObj;
- if (getsockname(fd, &him.sa, &len) == -1) {
+ if (getsockname(fd, &sa.sa, &len) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return NULL;
}
- iaObj = NET_SockaddrToInetAddress(env, &him.sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
return iaObj;
}
@@ -1969,6 +1971,7 @@
mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
#ifdef __linux__
mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr));
+ mname.imr_ifindex = 0;
#else
mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr));
#endif
@@ -2023,7 +2026,7 @@
#ifdef __linux__
mname.imr_address.s_addr = in.s_addr;
-
+ mname.imr_ifindex = 0;
#else
mname.imr_interface.s_addr = in.s_addr;
#endif
--- a/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -244,7 +244,7 @@
/* fd is an int field on iaObj */
jint fd;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
/* The result of the connection */
int connect_rv = -1;
@@ -260,17 +260,18 @@
}
/* connect */
- if (NET_InetAddressToSockaddr(env, iaObj, port, &him.sa, &len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, &len,
+ JNI_TRUE) != 0) {
return;
}
- setDefaultScopeID(env, &him.sa);
+ setDefaultScopeID(env, &sa.sa);
if (trafficClass != 0 && ipv6_available()) {
- NET_SetTrafficClass(&him.sa, trafficClass);
+ NET_SetTrafficClass(&sa, trafficClass);
}
if (timeout <= 0) {
- connect_rv = NET_Connect(fd, &him.sa, len);
+ connect_rv = NET_Connect(fd, &sa.sa, len);
#ifdef __solaris__
if (connect_rv == -1 && errno == EINPROGRESS ) {
@@ -319,7 +320,7 @@
SET_NONBLOCKING(fd);
/* no need to use NET_Connect as non-blocking */
- connect_rv = connect(fd, &him.sa, len);
+ connect_rv = connect(fd, &sa.sa, len);
/* connection not established immediately */
if (connect_rv != 0) {
@@ -467,11 +468,11 @@
* that the system chose for us and store it in the Socket object.
*/
socklen_t slen = sizeof(SOCKETADDRESS);
- if (getsockname(fd, &him.sa, &slen) == -1) {
+ if (getsockname(fd, &sa.sa, &slen) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
} else {
- localport = NET_GetPortFromSockaddr(&him.sa);
+ localport = NET_GetPortFromSockaddr(&sa);
(*env)->SetIntField(env, this, psi_localportID, localport);
}
}
@@ -490,8 +491,8 @@
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
/* fd is an int field on fdObj */
int fd;
- int len;
- SOCKETADDRESS him;
+ int len = 0;
+ SOCKETADDRESS sa;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -506,13 +507,13 @@
}
/* bind */
- if (NET_InetAddressToSockaddr(env, iaObj, localport, &him.sa,
+ if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa,
&len, JNI_TRUE) != 0) {
return;
}
- setDefaultScopeID(env, &him.sa);
+ setDefaultScopeID(env, &sa.sa);
- if (NET_Bind(fd, &him.sa, len) < 0) {
+ if (NET_Bind(fd, &sa, len) < 0) {
if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
errno == EPERM || errno == EACCES) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
@@ -533,12 +534,12 @@
/* Now that we're a connected socket, let's extract the port number
* that the system chose for us and store it in the Socket object.
*/
- if (getsockname(fd, &him.sa, &slen) == -1) {
+ if (getsockname(fd, &sa.sa, &slen) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return;
}
- localport = NET_GetPortFromSockaddr(&him.sa);
+ localport = NET_GetPortFromSockaddr(&sa);
(*env)->SetIntField(env, this, psi_localportID, localport);
} else {
(*env)->SetIntField(env, this, psi_localportID, localport);
@@ -606,7 +607,7 @@
/* accepted fd */
jint newfd;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
socklen_t slen = sizeof(SOCKETADDRESS);
if (IS_NULL(fdObj)) {
@@ -661,7 +662,7 @@
return;
}
- newfd = NET_Accept(fd, &him.sa, &slen);
+ newfd = NET_Accept(fd, &sa.sa, &slen);
/* connection accepted */
if (newfd >= 0) {
@@ -709,7 +710,7 @@
/*
* fill up the remote peer port and address in the new socket structure.
*/
- socketAddressObj = NET_SockaddrToInetAddress(env, &him.sa, &port);
+ socketAddressObj = NET_SockaddrToInetAddress(env, &sa, &port);
if (socketAddressObj == NULL) {
/* should be pending exception */
close(newfd);
@@ -944,19 +945,19 @@
* SO_BINDADDR isn't a socket option
*/
if (cmd == java_net_SocketOptions_SO_BINDADDR) {
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
socklen_t len = sizeof(SOCKETADDRESS);
int port;
jobject iaObj;
jclass iaCntrClass;
jfieldID iaFieldID;
- if (getsockname(fd, &him.sa, &len) < 0) {
+ if (getsockname(fd, &sa.sa, &len) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return -1;
}
- iaObj = NET_SockaddrToInetAddress(env, &him.sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
CHECK_NULL_RETURN(iaObj, -1);
iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Tue Jan 24 00:30:23 2017 +0100
@@ -234,29 +234,6 @@
}
return kernelV24;
}
-
-int getScopeID (struct sockaddr *him) {
- struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
- return hext->sin6_scope_id;
-}
-
-int cmpScopeID (unsigned int scope, struct sockaddr *him) {
- struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him;
- return hext->sin6_scope_id == scope;
-}
-
-#else
-
-int getScopeID (struct sockaddr *him) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- return him6->sin6_scope_id;
-}
-
-int cmpScopeID (unsigned int scope, struct sockaddr *him) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- return him6->sin6_scope_id == scope;
-}
-
#endif
void
@@ -775,30 +752,32 @@
return 0;
}
-/* In the case of an IPv4 Inetaddress this method will return an
- * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE.
- * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress.
-*/
+/**
+ * See net_util.h for documentation
+ */
JNIEXPORT int JNICALL
-NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
- int *len, jboolean v4MappedAddress) {
- jint family;
- family = getInetAddress_family(env, iaObj);
- /* needs work. 1. family 2. clean up him6 etc deallocate memory */
- if (ipv6_available() && !(family == java_net_InetAddress_IPv4 &&
- v4MappedAddress == JNI_FALSE)) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
+ SOCKETADDRESS *sa, int *len,
+ jboolean v4MappedAddress)
+{
+ jint family = getInetAddress_family(env, iaObj);
+ memset((char *)sa, 0, sizeof(SOCKETADDRESS));
+
+ if (ipv6_available() &&
+ !(family == java_net_InetAddress_IPv4 &&
+ v4MappedAddress == JNI_FALSE))
+ {
jbyte caddr[16];
jint address;
if (family == java_net_InetAddress_IPv4) {
// convert to IPv4-mapped address
- memset((char *) caddr, 0, 16);
+ memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address
- caddr[10] = 0xff;
- caddr[11] = 0xff; */
+ * caddr[10] = 0xff;
+ * caddr[11] = 0xff; */
} else {
caddr[10] = 0xff;
caddr[11] = 0xff;
@@ -810,22 +789,19 @@
} else {
getInet6Address_ipaddress(env, iaObj, (char *)caddr);
}
- memset((char *)him6, 0, sizeof(struct sockaddr_in6));
- him6->sin6_port = htons(port);
- memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
- him6->sin6_family = AF_INET6;
- *len = sizeof(struct sockaddr_in6);
+ sa->sa6.sin6_port = htons(port);
+ memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
+ sa->sa6.sin6_family = AF_INET6;
+ if (len != NULL) {
+ *len = sizeof(struct sockaddr_in6);
+ }
-#if defined(_ALLBSD_SOURCE)
-// XXXBSD: should we do something with scope id here ? see below linux comment
-/* MMM: Come back to this! */
-#endif
-
+#ifdef __linux__
/*
* On Linux if we are connecting to a link-local address
* we need to specify the interface in the scope_id (2.4 kernel only)
*
- * If the scope was cached the we use the cached value. If not cached but
+ * If the scope was cached then we use the cached value. If not cached but
* specified in the Inet6Address we use that, but we first check if the
* address needs to be routed via the loopback interface. In this case,
* we override the specified value with that of the loopback interface.
@@ -833,9 +809,8 @@
* we try to determine a value from the routing table. In all these
* cases the used value is cached for further use.
*/
-#ifdef __linux__
- if (IN6_IS_ADDR_LINKLOCAL(&(him6->sin6_addr))) {
- int cached_scope_id = 0, scope_id = 0;
+ if (IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr)) {
+ unsigned int cached_scope_id = 0, scope_id = 0;
if (ia6_cachedscopeidID) {
cached_scope_id = (int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
@@ -850,7 +825,7 @@
/* check user-specified value for loopback case
* that needs to be overridden
*/
- if (kernelIsV24() && needsLoopbackRoute (&him6->sin6_addr)) {
+ if (kernelIsV24() && needsLoopbackRoute(&sa->sa6.sin6_addr)) {
cached_scope_id = lo_scope_id;
(*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
}
@@ -860,11 +835,11 @@
* try determine the appropriate interface.
*/
if (kernelIsV24()) {
- cached_scope_id = getDefaultIPv6Interface(&(him6->sin6_addr));
+ cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
} else {
- cached_scope_id = getLocalScopeID((char *)&(him6->sin6_addr));
+ cached_scope_id = getLocalScopeID((char *)&(sa->sa6.sin6_addr));
if (cached_scope_id == 0) {
- cached_scope_id = getDefaultIPv6Interface(&(him6->sin6_addr));
+ cached_scope_id = getDefaultIPv6Interface(&sa->sa6.sin6_addr);
}
}
(*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
@@ -876,53 +851,37 @@
* If we have a scope_id use the extended form
* of sockaddr_in6.
*/
-
- struct sockaddr_in6 *him6 =
- (struct sockaddr_in6 *)him;
- him6->sin6_scope_id = cached_scope_id != 0 ?
- cached_scope_id : scope_id;
- *len = sizeof(struct sockaddr_in6);
+ sa->sa6.sin6_scope_id = cached_scope_id == 0 ? scope_id : cached_scope_id;
}
#else
- /* handle scope_id for solaris */
-
+ /* handle scope_id */
if (family != java_net_InetAddress_IPv4) {
if (ia6_scopeidID) {
- him6->sin6_scope_id = getInet6Address_scopeid(env, iaObj);
+ sa->sa6.sin6_scope_id = getInet6Address_scopeid(env, iaObj);
}
}
#endif
} else {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
jint address;
- if (family == java_net_InetAddress_IPv6) {
+ if (family != java_net_InetAddress_IPv4) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
return -1;
}
- memset((char *)him4, 0, sizeof(struct sockaddr_in));
address = getInetAddress_addr(env, iaObj);
- him4->sin_port = htons((short) port);
- him4->sin_addr.s_addr = htonl(address);
- him4->sin_family = AF_INET;
- *len = sizeof(struct sockaddr_in);
+ sa->sa4.sin_port = htons(port);
+ sa->sa4.sin_addr.s_addr = htonl(address);
+ sa->sa4.sin_family = AF_INET;
+ if (len != NULL) {
+ *len = sizeof(struct sockaddr_in);
+ }
}
return 0;
}
void
-NET_SetTrafficClass(struct sockaddr *him, int trafficClass) {
- if (him->sa_family == AF_INET6) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- him6->sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
- }
-}
-
-JNIEXPORT jint JNICALL
-NET_GetPortFromSockaddr(struct sockaddr *him) {
- if (him->sa_family == AF_INET6) {
- return ntohs(((struct sockaddr_in6*)him)->sin6_port);
- } else {
- return ntohs(((struct sockaddr_in*)him)->sin_port);
+NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass) {
+ if (sa->sa.sa_family == AF_INET6) {
+ sa->sa6.sin6_flowinfo = htonl((trafficClass & 0xff) << 20);
}
}
@@ -1488,7 +1447,7 @@
*
*/
int
-NET_Bind(int fd, struct sockaddr *him, int len)
+NET_Bind(int fd, SOCKETADDRESS *sa, int len)
{
#if defined(__solaris__)
int level = -1;
@@ -1503,9 +1462,8 @@
* ## When IPv6 is enabled this will be an IPv4-mapped
* ## with family set to AF_INET6
*/
- if (him->sa_family == AF_INET) {
- struct sockaddr_in *sa = (struct sockaddr_in *)him;
- if ((ntohl(sa->sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) {
+ if (sa->sa.sa_family == AF_INET) {
+ if ((ntohl(sa->sa4.sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) {
errno = EADDRNOTAVAIL;
return -1;
}
@@ -1524,8 +1482,9 @@
*/
alen = sizeof(arg);
- if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (char *)&arg, &alen) == 0) {
+ if (useExclBind ||
+ getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, &alen) == 0)
+ {
if (useExclBind || arg == 0) {
/*
* SO_REUSEADDR is disabled or sun.net.useExclusiveBind
@@ -1533,8 +1492,8 @@
* UDP_EXCLBIND
*/
alen = sizeof(arg);
- if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg,
- &alen) == 0) {
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, &alen) == 0)
+ {
if (arg == SOCK_STREAM) {
level = IPPROTO_TCP;
exclbind = TCP_EXCLBIND;
@@ -1545,14 +1504,13 @@
}
arg = 1;
- setsockopt(fd, level, exclbind, (char *)&arg,
- sizeof(arg));
+ setsockopt(fd, level, exclbind, (char *)&arg, sizeof(arg));
}
}
#endif
- rv = bind(fd, him, len);
+ rv = bind(fd, &sa->sa, len);
#if defined(__solaris__)
if (rv < 0) {
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h Tue Jan 24 00:30:23 2017 +0100
@@ -30,32 +30,6 @@
#include <sys/poll.h>
#include <sys/socket.h>
-int NET_Timeout(int s, long timeout);
-int NET_Timeout0(int s, long timeout, long currentTime);
-int NET_Read(int s, void* buf, size_t len);
-int NET_NonBlockingRead(int s, void* buf, size_t len);
-int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime);
-long NET_GetCurrentTime();
-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen);
-int NET_ReadV(int s, const struct iovec * vector, int count);
-int NET_Send(int s, void *msg, int len, unsigned int flags);
-int NET_SendTo(int s, const void *msg, int len, unsigned int
- flags, const struct sockaddr *to, int tolen);
-int NET_Writev(int s, const struct iovec * vector, int count);
-int NET_Connect(int s, struct sockaddr *addr, int addrlen);
-int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int NET_SocketClose(int s);
-int NET_Dup2(int oldfd, int newfd);
-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout);
-int NET_SocketAvailable(int s, jint *pbytes);
-
-void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
- const char* hostname,
- int gai_error);
-void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
- const char *defaultDetail);
-
/************************************************************************
* Macros and constants
*/
@@ -91,9 +65,36 @@
} SOCKETADDRESS;
/************************************************************************
- * Utilities
+ * Functions
*/
+int NET_Timeout(int s, long timeout);
+int NET_Timeout0(int s, long timeout, long currentTime);
+int NET_Read(int s, void* buf, size_t len);
+int NET_NonBlockingRead(int s, void* buf, size_t len);
+int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime);
+long NET_GetCurrentTime();
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, socklen_t *fromlen);
+int NET_ReadV(int s, const struct iovec * vector, int count);
+int NET_Send(int s, void *msg, int len, unsigned int flags);
+int NET_SendTo(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen);
+int NET_Writev(int s, const struct iovec * vector, int count);
+int NET_Connect(int s, struct sockaddr *addr, int addrlen);
+int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int NET_SocketClose(int s);
+int NET_Dup2(int oldfd, int newfd);
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout);
+int NET_SocketAvailable(int s, jint *pbytes);
+
+void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
+ const char* hostname,
+ int gai_error);
+void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
+ const char *defaultDetail);
+void NET_SetTrafficClass(SOCKETADDRESS *sa, int trafficClass);
+
#ifdef __linux__
int kernelIsV24();
int getDefaultIPv6Interface(struct in6_addr *target_addr);
--- a/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -181,11 +181,11 @@
*/
senderAddr = (*env)->GetObjectField(env, this, dci_senderAddrID);
if (senderAddr != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, &sa.sa, senderAddr)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &sa, senderAddr)) {
senderAddr = NULL;
} else {
jint port = (*env)->GetIntField(env, this, dci_senderPortID);
- if (port != NET_GetPortFromSockaddr(&sa.sa)) {
+ if (port != NET_GetPortFromSockaddr(&sa)) {
senderAddr = NULL;
}
}
@@ -193,7 +193,7 @@
if (senderAddr == NULL) {
jobject isa = NULL;
int port = 0;
- jobject ia = NET_SockaddrToInetAddress(env, &sa.sa, &port);
+ jobject ia = NET_SockaddrToInetAddress(env, &sa, &port);
if (ia != NULL) {
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
}
@@ -201,7 +201,7 @@
(*env)->SetObjectField(env, this, dci_senderAddrID, ia);
(*env)->SetIntField(env, this, dci_senderPortID,
- NET_GetPortFromSockaddr(&sa.sa));
+ NET_GetPortFromSockaddr(&sa));
(*env)->SetObjectField(env, this, dci_senderID, isa);
}
return n;
@@ -215,14 +215,14 @@
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
+ int sa_len = 0;
jint n = 0;
if (len > MAX_PACKET_LEN) {
len = MAX_PACKET_LEN;
}
- if (NET_InetAddressToSockaddr(env, destAddress, destPort, &sa.sa,
+ if (NET_InetAddressToSockaddr(env, destAddress, destPort, &sa,
&sa_len, preferIPv6) != 0) {
return IOS_THROWN;
}
--- a/jdk/src/java.base/unix/native/libnio/ch/InheritedChannel.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnio/ch/InheritedChannel.c Tue Jan 24 00:30:23 2017 +0100
@@ -64,7 +64,7 @@
if (getpeername(fd, &sa.sa, &len) == 0) {
if (matchFamily(&sa.sa)) {
- remote_ia = NET_SockaddrToInetAddress(env, &sa.sa, (int *)&remote_port);
+ remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
}
}
@@ -81,7 +81,7 @@
if (getpeername(fd, &sa.sa, &len) == 0) {
if (matchFamily(&sa.sa)) {
- NET_SockaddrToInetAddress(env, &sa.sa, (int *)&remote_port);
+ NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
}
}
--- a/jdk/src/java.base/unix/native/libnio/ch/Net.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnio/ch/Net.c Tue Jan 24 00:30:23 2017 +0100
@@ -274,15 +274,15 @@
jboolean useExclBind, jobject iao, int port)
{
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
+ int sa_len = 0;
int rv = 0;
- if (NET_InetAddressToSockaddr(env, iao, port, &sa.sa, &sa_len,
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
preferIPv6) != 0) {
return;
}
- rv = NET_Bind(fdval(env, fdo), &sa.sa, sa_len);
+ rv = NET_Bind(fdval(env, fdo), &sa, sa_len);
if (rv != 0) {
handleSocketError(env, errno);
}
@@ -300,10 +300,10 @@
jobject fdo, jobject iao, jint port)
{
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
+ int sa_len = 0;
int rv;
- if (NET_InetAddressToSockaddr(env, iao, port, &sa.sa, &sa_len,
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
preferIPv6) != 0) {
return IOS_THROWN;
}
@@ -349,7 +349,7 @@
return -1;
#endif /* _ALLBSD_SOURCE */
}
- return NET_GetPortFromSockaddr(&sa.sa);
+ return NET_GetPortFromSockaddr(&sa);
}
JNIEXPORT jobject JNICALL
@@ -382,7 +382,7 @@
return NULL;
#endif /* _ALLBSD_SOURCE */
}
- return NET_SockaddrToInetAddress(env, &sa.sa, &port);
+ return NET_SockaddrToInetAddress(env, &sa, &port);
}
JNIEXPORT jint JNICALL
--- a/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/unix/native/libnio/ch/ServerSocketChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -112,7 +112,7 @@
}
(*env)->SetIntField(env, newfdo, fd_fdID, newfd);
- remote_ia = NET_SockaddrToInetAddress(env, &sa.sa, (int *)&remote_port);
+ remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
CHECK_NULL_RETURN(isa, IOS_THROWN);
--- a/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -233,11 +233,14 @@
int childStart = 0;
int parentEnd = pn;
+ boolean isDirectoryRelative =
+ pn == 2 && isLetter(parent.charAt(0)) && parent.charAt(1) == ':';
+
if ((cn > 1) && (c.charAt(0) == slash)) {
if (c.charAt(1) == slash) {
/* Drop prefix when child is a UNC pathname */
childStart = 2;
- } else {
+ } else if (!isDirectoryRelative) {
/* Drop prefix when child is drive-relative */
childStart = 1;
@@ -254,7 +257,7 @@
int strlen = parentEnd + cn - childStart;
char[] theChars = null;
- if (child.charAt(childStart) == slash) {
+ if (child.charAt(childStart) == slash || isDirectoryRelative) {
theChars = new char[strlen];
parent.getChars(0, parentEnd, theChars, 0);
child.getChars(childStart, cn, theChars, parentEnd);
--- a/jdk/src/java.base/windows/native/libnet/DualStackPlainDatagramSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/DualStackPlainDatagramSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -53,7 +53,7 @@
break;
}
if (recvfrom(fd, buf, 1, MSG_PEEK,
- (struct sockaddr *)&rmtaddr, &addrlen) != SOCKET_ERROR) {
+ &rmtaddr.sa, &addrlen) != SOCKET_ERROR) {
break;
}
if (WSAGetLastError() != WSAECONNRESET) {
@@ -61,7 +61,7 @@
break;
}
- recvfrom(fd, buf, 1, 0, (struct sockaddr *)&rmtaddr, &addrlen);
+ recvfrom(fd, buf, 1, 0, &rmtaddr.sa, &addrlen);
got_icmp = JNI_TRUE;
}
@@ -134,14 +134,13 @@
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port, jboolean exclBind) {
SOCKETADDRESS sa;
- int rv;
- int sa_len = sizeof(sa);
+ int rv, sa_len = 0;
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, JNI_TRUE) != 0) {
return;
}
- rv = NET_WinBind(fd, (struct sockaddr *)&sa, sa_len, exclBind);
+ rv = NET_WinBind(fd, &sa, sa_len, exclBind);
if (rv == SOCKET_ERROR) {
if (WSAGetLastError() == WSAEACCES) {
@@ -159,17 +158,15 @@
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConnect
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
SOCKETADDRESS sa;
- int rv;
- int sa_len = sizeof(sa);
+ int rv, sa_len = 0, t = TRUE;
DWORD x1, x2; /* ignored result codes */
- int t = TRUE;
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, JNI_TRUE) != 0) {
return;
}
- rv = connect(fd, (struct sockaddr *)&sa, sa_len);
+ rv = connect(fd, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "connect");
return;
@@ -192,7 +189,7 @@
int t = FALSE;
memset(&sa, 0, sa_len);
- connect(fd, (struct sockaddr *)&sa, sa_len);
+ connect(fd, &sa.sa, sa_len);
/* see comment in socketCreate */
WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
@@ -219,7 +216,7 @@
SOCKETADDRESS sa;
int len = sizeof(sa);
- if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
+ if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "getsockname");
return -1;
}
@@ -238,12 +235,12 @@
jobject iaObj;
int port;
- if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
+ if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
return NULL;
}
- iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
return iaObj;
}
@@ -316,7 +313,7 @@
/* receive the packet */
rv = recvfrom(fd, fullPacket, packetBufferLen, flags,
- (struct sockaddr *)&sa, &sa_len);
+ &sa.sa, &sa_len);
if (rv == SOCKET_ERROR && (WSAGetLastError() == WSAECONNRESET)) {
/* An icmp port unreachable - we must receive this as Windows
@@ -383,15 +380,13 @@
*/
packetAddress = (*env)->GetObjectField(env, dpObj, dp_addressID);
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&sa,
- packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &sa, packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa,
- &port);
+ packetAddress = NET_SockaddrToInetAddress(env, &sa, &port);
if (packetAddress != NULL) {
/* stuff the new Inetaddress into the packet */
(*env)->SetObjectField(env, dpObj, dp_addressID, packetAddress);
@@ -422,20 +417,18 @@
(JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint offset, jint length,
jobject iaObj, jint port, jboolean connected) {
SOCKETADDRESS sa;
- int sa_len = sizeof(sa);
- SOCKETADDRESS *sap = &sa;
+ int rv, sa_len = 0;
+ struct sockaddr *sap = 0;
char BUF[MAX_BUFFER_LEN];
char *fullPacket;
- int rv;
- if (connected) {
- sap = 0; /* arg to sendto () null in this case */
- sa_len = 0;
- } else {
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
- &sa_len, JNI_TRUE) != 0) {
+ // if already connected, sap arg to sendto() is null
+ if (!connected) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+ &sa_len, JNI_TRUE) != 0) {
return;
}
+ sap = &sa.sa;
}
if (length > MAX_BUFFER_LEN) {
@@ -456,7 +449,7 @@
(*env)->GetByteArrayRegion(env, data, offset, length,
(jbyte *)fullPacket);
- rv = sendto(fd, fullPacket, length, 0, (struct sockaddr *)sap, sa_len);
+ rv = sendto(fd, fullPacket, length, 0, sap, sa_len);
if (rv == SOCKET_ERROR) {
if (rv == -1) {
NET_ThrowNew(env, WSAGetLastError(), "Datagram send failed");
--- a/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -89,15 +89,14 @@
jboolean exclBind)
{
SOCKETADDRESS sa;
- int rv;
- int sa_len = sizeof(sa);
+ int rv, sa_len = 0;
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
- &sa_len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+ &sa_len, JNI_TRUE) != 0) {
return;
}
- rv = NET_WinBind(fd, (struct sockaddr *)&sa, sa_len, exclBind);
+ rv = NET_WinBind(fd, &sa, sa_len, exclBind);
if (rv == SOCKET_ERROR)
NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
@@ -111,15 +110,14 @@
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_connect0
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
SOCKETADDRESS sa;
- int rv;
- int sa_len = sizeof(sa);
+ int rv, sa_len = 0;
- if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
- &sa_len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+ &sa_len, JNI_TRUE) != 0) {
return -1;
}
- rv = connect(fd, (struct sockaddr *)&sa, sa_len);
+ rv = connect(fd, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
@@ -217,7 +215,7 @@
SOCKETADDRESS sa;
int len = sizeof(sa);
- if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
+ if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
if (WSAGetLastError() == WSAENOTSOCK) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
@@ -243,11 +241,11 @@
jclass iaContainerClass;
jfieldID iaFieldID;
- if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
+ if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
return;
}
- iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
CHECK_NULL(iaObj);
iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
@@ -283,7 +281,7 @@
int len = sizeof(sa);
memset((char *)&sa, 0, len);
- newfd = accept(fd, (struct sockaddr *)&sa, &len);
+ newfd = accept(fd, &sa.sa, &len);
if (newfd == INVALID_SOCKET) {
if (WSAGetLastError() == -2) {
@@ -298,7 +296,7 @@
SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
- ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ ia = NET_SockaddrToInetAddress(env, &sa, &port);
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -420,18 +420,13 @@
jboolean exclBind) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
-
- int fd, fd1 = -1, family;
int ipv6_supported = ipv6_available();
-
+ int fd, fd1 = -1, lcladdrlen = 0;
SOCKETADDRESS lcladdr;
- int lcladdrlen = sizeof(SOCKETADDRESS);
- int address;
- memset((char *)&lcladdr, 0, sizeof(lcladdr));
-
- family = getInetAddress_family(env, addressObj);
- if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
+ if (getInetAddress_family(env, addressObj) == java_net_InetAddress_IPv6 &&
+ !ipv6_supported)
+ {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported");
return;
@@ -446,14 +441,13 @@
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
}
}
+
if (IS_NULL(addressObj)) {
JNU_ThrowNullPointerException(env, "argument address");
return;
- } else {
- address = getInetAddress_addr(env, addressObj);
}
- if (NET_InetAddressToSockaddr(env, addressObj, port, &lcladdr.sa,
+ if (NET_InetAddressToSockaddr(env, addressObj, port, &lcladdr,
&lcladdrlen, JNI_FALSE) != 0) {
return;
}
@@ -493,7 +487,7 @@
return;
}
} else {
- if (NET_WinBind(fd, &lcladdr.sa, lcladdrlen, exclBind) == -1) {
+ if (NET_WinBind(fd, &lcladdr, lcladdrlen, exclBind) == -1) {
if (WSAGetLastError() == WSAEACCES) {
WSASetLastError(WSAEADDRINUSE);
}
@@ -507,7 +501,7 @@
NET_ThrowCurrent(env, "getsockname");
return;
}
- port = ntohs((u_short) GET_PORT (&lcladdr));
+ port = ntohs((u_short)GET_PORT(&lcladdr));
}
(*env)->SetIntField(env, this, pdsi_localPortID, port);
}
@@ -520,27 +514,25 @@
*/
JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject this,
- jobject address, jint port) {
- /* The object's field */
+Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0
+ (JNIEnv *env, jobject this, jobject address, jint port)
+{
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
- /* The fdObj'fd */
- jint fd=-1, fd1=-1, fdc;
- /* The packetAddress address, family and port */
- jint addr, family;
+ jint fd = -1, fd1 = -1, fdc, family;
SOCKETADDRESS rmtaddr;
- int rmtaddrlen;
- int ipv6_supported = ipv6_available();
+ int rmtaddrlen = 0;
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
}
+
if (!IS_NULL(fdObj)) {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
+
if (!IS_NULL(fd1Obj)) {
fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
}
@@ -550,10 +542,8 @@
return;
}
- addr = getInetAddress_addr(env, address);
-
family = getInetAddress_family(env, address);
- if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
+ if (family == java_net_InetAddress_IPv6 && !ipv6_available()) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported");
return;
@@ -572,12 +562,12 @@
res = WSAIoctl(fdc,SIO_UDP_CONNRESET,&t,sizeof(t),&x1,sizeof(x1),&x2,0,0);
}
- if (NET_InetAddressToSockaddr(env, address, port, &rmtaddr.sa,
+ if (NET_InetAddressToSockaddr(env, address, port, &rmtaddr,
&rmtaddrlen, JNI_FALSE) != 0) {
return;
}
- if (connect(fdc, &rmtaddr.sa, sizeof(rmtaddr)) == -1) {
+ if (connect(fdc, &rmtaddr.sa, rmtaddrlen) == -1) {
NET_ThrowCurrent(env, "connect");
return;
}
@@ -631,9 +621,9 @@
* Signature: (Ljava/net/DatagramPacket;)V
*/
JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
- jobject packet) {
-
+Java_java_net_TwoStacksPlainDatagramSocketImpl_send
+ (JNIEnv *env, jobject this, jobject packet)
+{
char BUF[MAX_BUFFER_LEN];
char *fullPacket;
jobject fdObj;
@@ -647,11 +637,10 @@
jbyteArray packetBuffer;
jboolean connected;
- SOCKETADDRESS rmtaddr, *addrp = &rmtaddr;
+ SOCKETADDRESS rmtaddr;
+ struct sockaddr *addrp = 0;
int addrlen = 0;
- memset((char *)&rmtaddr, 0, sizeof(rmtaddr));
-
if (IS_NULL(packet)) {
JNU_ThrowNullPointerException(env, "null packet");
return;
@@ -696,14 +685,13 @@
packetBufferLen = MAX_PACKET_LEN;
}
- if (connected) {
- addrp = 0; /* arg to sendto () null in this case */
- addrlen = 0;
- } else {
- if (NET_InetAddressToSockaddr(env, iaObj, packetPort, &rmtaddr.sa,
+ // sockaddr arg to sendto() is null if already connected
+ if (!connected) {
+ if (NET_InetAddressToSockaddr(env, iaObj, packetPort, &rmtaddr,
&addrlen, JNI_FALSE) != 0) {
return;
}
+ addrp = &rmtaddr.sa;
}
if (packetBufferLen > MAX_BUFFER_LEN) {
@@ -753,11 +741,12 @@
fullPacket = &(BUF[0]);
}
- (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
- (jbyte *)fullPacket);
- if (sendto(fd, fullPacket, packetBufferLen, 0,
- (struct sockaddr *)addrp, addrlen) == SOCKET_ERROR) {
- NET_ThrowCurrent(env, "Datagram send failed");
+ (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset,
+ packetBufferLen, (jbyte *)fullPacket);
+ if (sendto(fd, fullPacket, packetBufferLen, 0, addrp,
+ addrlen) == SOCKET_ERROR)
+ {
+ NET_ThrowCurrent(env, "Datagram send failed");
}
if (packetBufferLen > MAX_BUFFER_LEN) {
@@ -1147,14 +1136,14 @@
*/
packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, &remote_addr.sa,
+ if (!NET_SockaddrEqualsInetAddress(env, &remote_addr,
packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, &remote_addr.sa,
+ packetAddress = NET_SockaddrToInetAddress(env, &remote_addr,
&port);
/* stuff the new Inetaddress in the packet */
(*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
@@ -1431,20 +1420,21 @@
* can't update any existing InetAddress because it is immutable
*/
packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
-
if (packetAddress != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, &remote_addr.sa, packetAddress)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &remote_addr,
+ packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (packetAddress == NULL) {
- packetAddress = NET_SockaddrToInetAddress(env, &remote_addr.sa, &port);
+ packetAddress = NET_SockaddrToInetAddress(env, &remote_addr,
+ &port);
/* stuff the new Inetaddress in the packet */
(*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
} else {
/* only get the new port number */
- port = NET_GetPortFromSockaddr(&remote_addr.sa);
+ port = NET_GetPortFromSockaddr(&remote_addr);
}
/* populate the packet */
(*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
@@ -1528,7 +1518,7 @@
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jobject fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
int ipv6_supported = ipv6_available();
- int fd=-1, fd1=-1;
+ int fd = -1, fd1 = -1;
if (IS_NULL(fdObj) && (!ipv6_supported || IS_NULL(fd1Obj))) {
return;
@@ -1799,7 +1789,7 @@
Java_java_net_TwoStacksPlainDatagramSocketImpl_socketNativeSetOption
(JNIEnv *env,jobject this, jint opt,jobject value)
{
- int fd=-1, fd1=-1;
+ int fd = -1, fd1 = -1;
int levelv4 = 0, levelv6 = 0, optnamev4 = 0, optnamev6 = 0, optlen = 0;
union {
int i;
@@ -2167,7 +2157,7 @@
Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption
(JNIEnv *env, jobject this, jint opt)
{
- int fd=-1, fd1=-1;
+ int fd = -1, fd1 = -1;
int level, optname, optlen;
union {
int i;
@@ -2255,7 +2245,7 @@
(JNIEnv *env, jobject this, jint family)
{
int fd = -1, fd1 = -1;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
int len = 0;
int port;
jobject iaObj;
@@ -2288,12 +2278,12 @@
return NULL;
}
- if (getsockname(fd, &him.sa, &len) == -1) {
+ if (getsockname(fd, &sa.sa, &len) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return NULL;
}
- iaObj = NET_SockaddrToInetAddress(env, &him.sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
return iaObj;
}
@@ -2430,7 +2420,7 @@
int len, family;
int ipv6_supported = ipv6_available();
- int cmd ;
+ int cmd;
memset((char *)&in, 0, sizeof(in));
memset((char *)&name, 0, sizeof(name));
@@ -2452,7 +2442,7 @@
return;
}
- if (NET_InetAddressToSockaddr(env, iaObj, 0, &name.sa, &len, JNI_FALSE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, 0, &name, &len, JNI_FALSE) != 0) {
return;
}
@@ -2473,7 +2463,7 @@
return;
}
if (IS_NULL(niObj)) {
- len = sizeof (in);
+ len = sizeof(in);
if (NET_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&in, &len) < 0) {
NET_ThrowCurrent(env, "get IP_MULTICAST_IF failed");
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -175,8 +175,8 @@
*/
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
- jobject iaObj, jint port,
- jint timeout)
+ jobject iaObj, jint port,
+ jint timeout)
{
jint localport = (*env)->GetIntField(env, this, psi_localportID);
@@ -193,11 +193,11 @@
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
/* The result of the connection */
int connect_res;
- memset((char *)&him, 0, sizeof(him));
+ memset((char *)&sa, 0, sizeof(sa));
if (!IS_NULL(fdObj)) {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
@@ -212,11 +212,12 @@
return;
}
- if (NET_InetAddressToSockaddr(env, iaObj, port, &him.sa, &len, JNI_FALSE) != 0) {
- return;
+ if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, &len,
+ JNI_FALSE) != 0) {
+ return;
}
- family = him.sa.sa_family;
+ family = sa.sa.sa_family;
if (family == AF_INET6) {
if (!ipv6_supported) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -248,7 +249,7 @@
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
if (timeout <= 0) {
- connect_res = connect(fd, &him.sa, sizeof(SOCKETADDRESS));
+ connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
if (connect_res == SOCKET_ERROR) {
connect_res = WSAGetLastError();
}
@@ -261,7 +262,7 @@
ioctlsocket(fd, FIONBIO, &optval);
/* initiate the connect */
- connect_res = connect(fd, &him.sa, sizeof(SOCKETADDRESS));
+ connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
if (connect_res == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
connect_res = WSAGetLastError();
@@ -362,7 +363,7 @@
*/
u_short port;
int len = sizeof(SOCKETADDRESS);
- if (getsockname(fd, &him.sa, &len) == -1) {
+ if (getsockname(fd, &sa.sa, &len) == -1) {
if (WSAGetLastError() == WSAENOTSOCK) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
@@ -371,7 +372,7 @@
}
return;
}
- port = ntohs((u_short)GET_PORT(&him));
+ port = ntohs((u_short)GET_PORT(&sa));
(*env)->SetIntField(env, this, psi_localportID, (int) port);
}
}
@@ -396,7 +397,7 @@
int family;
int rv;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
@@ -424,13 +425,13 @@
return;
}
- if (NET_InetAddressToSockaddr(env, iaObj, localport, &him.sa, &len,
+ if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa, &len,
JNI_FALSE) != 0) {
return;
}
if (ipv6_supported) {
struct ipv6bind v6bind;
- v6bind.addr = &him;
+ v6bind.addr = &sa.sa;
v6bind.ipv4_fd = fd;
v6bind.ipv6_fd = fd1;
rv = NET_BindV6(&v6bind, exclBind);
@@ -462,7 +463,7 @@
(*env)->SetObjectField(env, this, psi_fd1ID, NULL);
}
} else {
- rv = NET_WinBind(fd, &him.sa, len, exclBind);
+ rv = NET_WinBind(fd, &sa, len, exclBind);
}
if (rv == -1) {
@@ -481,11 +482,11 @@
int len = sizeof(SOCKETADDRESS);
u_short port;
- if (getsockname(him.sa.sa_family == AF_INET ? fd: fd1, &him.sa, &len) == -1) {
+ if (getsockname(sa.sa.sa_family == AF_INET ? fd : fd1, &sa.sa, &len) == -1) {
NET_ThrowCurrent(env, "getsockname in plain socketBind");
return;
}
- port = ntohs((u_short) GET_PORT (&him));
+ port = ntohs((u_short) GET_PORT (&sa));
(*env)->SetIntField(env, this, psi_localportID, (int)port);
} else {
@@ -529,7 +530,7 @@
JNU_ThrowNullPointerException(env, "socket address");
return;
}
- if (NET_InetAddressToSockaddr(env, address, 0, &addr.sa, &addrlen,
+ if (NET_InetAddressToSockaddr(env, address, 0, &addr, &addrlen,
JNI_FALSE) != 0) {
return;
}
@@ -585,7 +586,7 @@
/* the fd int field on fdObj */
jint fd=-1, fd1=-1;
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
jint len;
if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
@@ -676,7 +677,7 @@
}
}
}
- fd = accept(fd, &him.sa, &len);
+ fd = accept(fd, &sa.sa, &len);
if (fd < 0) {
/* REMIND: SOCKET CLOSED PROBLEM */
if (fd == -2) {
@@ -691,7 +692,7 @@
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
- if (him.sa.sa_family == AF_INET) {
+ if (sa.sa.sa_family == AF_INET) {
if (inet4Cls == NULL) {
jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
if (c != NULL) {
@@ -717,7 +718,7 @@
return;
}
- setInetAddress_addr(env, socketAddressObj, ntohl(him.sa4.sin_addr.s_addr));
+ setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
(*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
} else {
@@ -743,14 +744,14 @@
NET_SocketClose(fd);
return;
}
- setInet6Address_ipaddress(env, socketAddressObj, (char *)&him.sa6.sin6_addr);
+ setInet6Address_ipaddress(env, socketAddressObj, (char *)&sa.sa6.sin6_addr);
setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv6);
- setInet6Address_scopeid(env, socketAddressObj, him.sa6.sin6_scope_id);
+ setInet6Address_scopeid(env, socketAddressObj, sa.sa6.sin6_scope_id);
}
/* fields common to AF_INET and AF_INET6 */
- port = ntohs ((u_short) GET_PORT (&him));
+ port = ntohs ((u_short)GET_PORT(&sa));
(*env)->SetIntField(env, socket, psi_portID, (int)port);
port = (*env)->GetIntField(env, this, psi_localportID);
(*env)->SetIntField(env, socket, psi_localportID, port);
@@ -1025,14 +1026,14 @@
* SO_BINDADDR isn't a socket option
*/
if (opt == java_net_SocketOptions_SO_BINDADDR) {
- SOCKETADDRESS him;
+ SOCKETADDRESS sa;
int len = sizeof(SOCKETADDRESS);
int port;
jobject iaObj;
jclass iaCntrClass;
jfieldID iaFieldID;
- memset((char *)&him, 0, len);
+ memset((char *)&sa, 0, len);
if (fd == -1) {
/* must be an IPV6 only socket. Case where both sockets are != -1
@@ -1041,12 +1042,12 @@
fd = getFD1 (env, this);
}
- if (getsockname(fd, &him.sa, &len) < 0) {
+ if (getsockname(fd, &sa.sa, &len) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return -1;
}
- iaObj = NET_SockaddrToInetAddress(env, &him.sa, &port);
+ iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
CHECK_NULL_RETURN(iaObj, -1);
iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c Tue Jan 24 00:30:23 2017 +0100
@@ -488,10 +488,10 @@
* Should be only called by the wrapper method NET_WinBind
*/
JNIEXPORT int JNICALL
-NET_Bind(int s, struct sockaddr *him, int len)
+NET_Bind(int s, SOCKETADDRESS *sa, int len)
{
int rv = 0;
- rv = bind(s, him, len);
+ rv = bind(s, &sa->sa, len);
if (rv == SOCKET_ERROR) {
/*
@@ -511,11 +511,11 @@
* if required, and then calls NET_BIND
*/
JNIEXPORT int JNICALL
-NET_WinBind(int s, struct sockaddr *him, int len, jboolean exclBind)
+NET_WinBind(int s, SOCKETADDRESS *sa, int len, jboolean exclBind)
{
if (exclBind == JNI_TRUE)
setExclusiveBind(s);
- return NET_Bind(s, him, len);
+ return NET_Bind(s, sa, len);
}
JNIEXPORT int JNICALL
@@ -677,8 +677,8 @@
if (family == AF_INET && (b->addr->sa4.sin_addr.s_addr != INADDR_ANY)) {
/* bind to v4 only */
int ret;
- ret = NET_WinBind((int)b->ipv4_fd, (struct sockaddr *)b->addr,
- sizeof(SOCKETADDRESS), exclBind);
+ ret = NET_WinBind((int)b->ipv4_fd, b->addr,
+ sizeof(SOCKETADDRESS), exclBind);
if (ret == SOCKET_ERROR) {
CLOSE_SOCKETS_AND_RETURN;
}
@@ -689,7 +689,7 @@
if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->sa6.sin6_addr))) {
/* bind to v6 only */
int ret;
- ret = NET_WinBind((int)b->ipv6_fd, (struct sockaddr *)b->addr,
+ ret = NET_WinBind((int)b->ipv6_fd, b->addr,
sizeof(SOCKETADDRESS), exclBind);
if (ret == SOCKET_ERROR) {
CLOSE_SOCKETS_AND_RETURN;
@@ -719,7 +719,7 @@
oaddr.sa4.sin_addr.s_addr = INADDR_ANY;
}
- rv = NET_WinBind(fd, (struct sockaddr *)b->addr, sizeof(SOCKETADDRESS), exclBind);
+ rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind);
if (rv == SOCKET_ERROR) {
CLOSE_SOCKETS_AND_RETURN;
}
@@ -731,7 +731,7 @@
}
bound_port = GET_PORT (b->addr);
SET_PORT (&oaddr, bound_port);
- if ((rv = NET_WinBind(ofd, &oaddr.sa,
+ if ((rv = NET_WinBind(ofd, &oaddr,
sizeof(SOCKETADDRESS), exclBind)) == SOCKET_ERROR) {
int retries;
int sotype, arglen=sizeof(sotype);
@@ -768,7 +768,7 @@
/* bind random port on first socket */
SET_PORT (&oaddr, 0);
- rv = NET_WinBind(ofd, &oaddr.sa, sizeof(SOCKETADDRESS), exclBind);
+ rv = NET_WinBind(ofd, &oaddr, sizeof(SOCKETADDRESS), exclBind);
if (rv == SOCKET_ERROR) {
CLOSE_SOCKETS_AND_RETURN;
}
@@ -784,8 +784,7 @@
}
bound_port = GET_PORT (&oaddr);
SET_PORT (b->addr, bound_port);
- rv = NET_WinBind(fd, (struct sockaddr *)b->addr,
- sizeof(SOCKETADDRESS), exclBind);
+ rv = NET_WinBind(fd, b->addr, sizeof(SOCKETADDRESS), exclBind);
if (rv != SOCKET_ERROR) {
if (family == AF_INET) {
@@ -853,31 +852,33 @@
return result == SOCKET_ERROR ? WSAGetLastError() : 0;
}
-/* If address types is IPv6, then IPv6 must be available. Otherwise
- * no address can be generated. In the case of an IPv4 Inetaddress this
- * method will return an IPv4 mapped address where IPv6 is available and
- * v4MappedAddress is TRUE. Otherwise it will return a sockaddr_in
- * structure for an IPv4 InetAddress.
-*/
+/**
+ * See net_util.h for documentation
+ */
JNIEXPORT int JNICALL
-NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him,
- int *len, jboolean v4MappedAddress) {
- jint family, iafam;
- iafam = getInetAddress_family(env, iaObj);
- family = (iafam == java_net_InetAddress_IPv4)? AF_INET : AF_INET6;
- if (ipv6_available() && !(family == AF_INET && v4MappedAddress == JNI_FALSE)) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
+ SOCKETADDRESS *sa, int *len,
+ jboolean v4MappedAddress)
+{
+ jint family = getInetAddress_family(env, iaObj);
+ memset((char *)sa, 0, sizeof(SOCKETADDRESS));
+
+ if (ipv6_available() &&
+ !(family == java_net_InetAddress_IPv4 &&
+ v4MappedAddress == JNI_FALSE))
+ {
jbyte caddr[16];
- jint address, scopeid = 0;
- jint cached_scope_id = 0;
+ jint address;
+ unsigned int scopeid = 0, cached_scope_id = 0;
- if (family == AF_INET) { /* will convert to IPv4-mapped address */
- memset((char *) caddr, 0, 16);
+ if (family == java_net_InetAddress_IPv4) {
+ // convert to IPv4-mapped address
+ memset((char *)caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
if (address == INADDR_ANY) {
/* we would always prefer IPv6 wildcard address
- caddr[10] = 0xff;
- caddr[11] = 0xff; */
+ * caddr[10] = 0xff;
+ * caddr[11] = 0xff; */
} else {
caddr[10] = 0xff;
caddr[11] = 0xff;
@@ -889,46 +890,39 @@
} else {
getInet6Address_ipaddress(env, iaObj, (char *)caddr);
scopeid = getInet6Address_scopeid(env, iaObj);
- cached_scope_id = (jint)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
+ cached_scope_id = (unsigned int)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
}
-
- memset((char *)him6, 0, sizeof(struct sockaddr_in6));
- him6->sin6_port = (u_short) htons((u_short)port);
- memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
- him6->sin6_family = AF_INET6;
- if ((family == AF_INET6) && IN6_IS_ADDR_LINKLOCAL( &(him6->sin6_addr) )
- && (!scopeid && !cached_scope_id)) {
- cached_scope_id = getDefaultIPv6Interface(env, him6);
+ sa->sa6.sin6_port = (u_short)htons((u_short)port);
+ memcpy((void *)&sa->sa6.sin6_addr, caddr, sizeof(struct in6_addr));
+ sa->sa6.sin6_family = AF_INET6;
+ if ((family == java_net_InetAddress_IPv6) &&
+ IN6_IS_ADDR_LINKLOCAL(&sa->sa6.sin6_addr) &&
+ (!scopeid && !cached_scope_id))
+ {
+ cached_scope_id = getDefaultIPv6Interface(env, &sa->sa6);
(*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
}
- him6->sin6_scope_id = scopeid != 0 ? scopeid : cached_scope_id;
- *len = sizeof(struct sockaddr_in6) ;
+ sa->sa6.sin6_scope_id = scopeid == 0 ? cached_scope_id : scopeid;
+ if (len != NULL) {
+ *len = sizeof(struct sockaddr_in6);
+ }
} else {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
jint address;
- if (family != AF_INET) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
- return -1;
+ if (family != java_net_InetAddress_IPv4) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
+ return -1;
}
- memset((char *)him4, 0, sizeof(struct sockaddr_in));
address = getInetAddress_addr(env, iaObj);
- him4->sin_port = htons((short) port);
- him4->sin_addr.s_addr = (u_long) htonl(address);
- him4->sin_family = AF_INET;
- *len = sizeof(struct sockaddr_in);
+ sa->sa4.sin_port = htons((short)port);
+ sa->sa4.sin_addr.s_addr = (u_long)htonl(address);
+ sa->sa4.sin_family = AF_INET;
+ if (len != NULL) {
+ *len = sizeof(struct sockaddr_in);
+ }
}
return 0;
}
-JNIEXPORT jint JNICALL
-NET_GetPortFromSockaddr(struct sockaddr *him) {
- if (him->sa_family == AF_INET6) {
- return ntohs(((struct sockaddr_in6 *)him)->sin6_port);
- } else {
- return ntohs(((struct sockaddr_in *)him)->sin_port);
- }
-}
-
int
NET_IsIPv4Mapped(jbyte* caddr) {
int i;
@@ -961,16 +955,6 @@
return 1;
}
-int getScopeID(struct sockaddr *him) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- return him6->sin6_scope_id;
-}
-
-int cmpScopeID(unsigned int scope, struct sockaddr *him) {
- struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
- return him6->sin6_scope_id == scope;
-}
-
/**
* Wrapper for select/poll with timeout on a single file descriptor.
*
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.h Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.h Tue Jan 24 00:30:23 2017 +0100
@@ -121,7 +121,7 @@
JNIEXPORT int JNICALL NET_BindV6(struct ipv6bind *b, jboolean exclBind);
-JNIEXPORT int JNICALL NET_WinBind(int s, struct sockaddr *him, int len,
+JNIEXPORT int JNICALL NET_WinBind(int s, SOCKETADDRESS *sa, int len,
jboolean exclBind);
/* XP versions of the native routines */
--- a/jdk/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -96,7 +96,7 @@
break;
}
if (recvfrom(fd, buf, 1, MSG_PEEK,
- (struct sockaddr *)&sa, &addrlen) != SOCKET_ERROR) {
+ &sa.sa, &addrlen) != SOCKET_ERROR) {
break;
}
if (WSAGetLastError() != WSAECONNRESET) {
@@ -104,7 +104,7 @@
break;
}
- recvfrom(fd, buf, 1, 0, (struct sockaddr *)&sa, &addrlen);
+ recvfrom(fd, buf, 1, 0, &sa.sa, &addrlen);
got_icmp = JNI_TRUE;
}
@@ -122,7 +122,7 @@
memset(&sa, 0, sa_len);
- rv = connect((SOCKET)fd, (struct sockaddr *)&sa, sa_len);
+ rv = connect((SOCKET)fd, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
handleSocketError(env, WSAGetLastError());
} else {
@@ -153,7 +153,7 @@
(char *)buf,
len,
0,
- (struct sockaddr *)&sa,
+ &sa.sa,
&sa_len);
if (n == SOCKET_ERROR) {
@@ -182,12 +182,11 @@
*/
senderAddr = (*env)->GetObjectField(env, this, dci_senderAddrID);
if (senderAddr != NULL) {
- if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&sa,
- senderAddr)) {
+ if (!NET_SockaddrEqualsInetAddress(env, &sa, senderAddr)) {
senderAddr = NULL;
} else {
jint port = (*env)->GetIntField(env, this, dci_senderPortID);
- if (port != NET_GetPortFromSockaddr((struct sockaddr *)&sa)) {
+ if (port != NET_GetPortFromSockaddr(&sa)) {
senderAddr = NULL;
}
}
@@ -195,7 +194,7 @@
if (senderAddr == NULL) {
jobject isa = NULL;
int port;
- jobject ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ jobject ia = NET_SockaddrToInetAddress(env, &sa, &port);
if (ia != NULL) {
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
}
@@ -204,7 +203,7 @@
// update cachedSenderInetAddress/cachedSenderPort
(*env)->SetObjectField(env, this, dci_senderAddrID, ia);
(*env)->SetIntField(env, this, dci_senderPortID,
- NET_GetPortFromSockaddr((struct sockaddr *)&sa));
+ NET_GetPortFromSockaddr(&sa));
(*env)->SetObjectField(env, this, dci_senderID, isa);
}
return n;
@@ -219,21 +218,15 @@
jint fd = fdval(env, fdo);
void *buf = (void *)jlong_to_ptr(address);
SOCKETADDRESS sa;
- int sa_len;
+ int sa_len = 0;
jint rv = 0;
- if (NET_InetAddressToSockaddr(env, destAddress, destPort,
- (struct sockaddr *)&sa,
- &sa_len, preferIPv6) != 0) {
+ if (NET_InetAddressToSockaddr(env, destAddress, destPort, &sa,
+ &sa_len, preferIPv6) != 0) {
return IOS_THROWN;
}
- rv = sendto((SOCKET)fd,
- buf,
- len,
- 0,
- (struct sockaddr *)&sa,
- sa_len);
+ rv = sendto((SOCKET)fd, buf, len, 0, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
int theErr = (jint)WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
--- a/jdk/src/java.base/windows/native/libnio/ch/Net.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnio/ch/Net.c Tue Jan 24 00:30:23 2017 +0100
@@ -168,13 +168,13 @@
{
SOCKETADDRESS sa;
int rv;
- int sa_len;
+ int sa_len = 0;
- if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
- return;
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len, preferIPv6) != 0) {
+ return;
}
- rv = NET_WinBind(fdval(env, fdo), (struct sockaddr *)&sa, sa_len, isExclBind);
+ rv = NET_WinBind(fdval(env, fdo), &sa, sa_len, isExclBind);
if (rv == SOCKET_ERROR)
NET_ThrowNew(env, WSAGetLastError(), "bind");
}
@@ -194,14 +194,14 @@
{
SOCKETADDRESS sa;
int rv;
- int sa_len;
+ int sa_len = 0;
SOCKET s = (SOCKET)fdval(env, fdo);
- if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len, preferIPv6) != 0) {
return IOS_THROWN;
}
- rv = connect(s, (struct sockaddr *)&sa, sa_len);
+ rv = connect(s, &sa.sa, sa_len);
if (rv != 0) {
int err = WSAGetLastError();
if (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK) {
@@ -226,7 +226,7 @@
SOCKETADDRESS sa;
int sa_len = sizeof(sa);
- if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+ if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
int error = WSAGetLastError();
if (error == WSAEINVAL) {
return 0;
@@ -234,7 +234,7 @@
NET_ThrowNew(env, error, "getsockname");
return IOS_THROWN;
}
- return NET_GetPortFromSockaddr((struct sockaddr *)&sa);
+ return NET_GetPortFromSockaddr(&sa);
}
JNIEXPORT jobject JNICALL
@@ -244,11 +244,11 @@
int sa_len = sizeof(sa);
int port;
- if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+ if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "getsockname");
return NULL;
}
- return NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ return NET_SockaddrToInetAddress(env, &sa, &port);
}
JNIEXPORT jint JNICALL
@@ -257,7 +257,7 @@
SOCKETADDRESS sa;
int sa_len = sizeof(sa);
- if (getpeername(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+ if (getpeername(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
int error = WSAGetLastError();
if (error == WSAEINVAL) {
return 0;
@@ -265,7 +265,7 @@
NET_ThrowNew(env, error, "getsockname");
return IOS_THROWN;
}
- return NET_GetPortFromSockaddr((struct sockaddr *)&sa);
+ return NET_GetPortFromSockaddr(&sa);
}
JNIEXPORT jobject JNICALL
@@ -275,11 +275,11 @@
int sa_len = sizeof(sa);
int port;
- if (getpeername(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+ if (getpeername(fdval(env, fdo), &sa.sa, &sa_len) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "getsockname");
return NULL;
}
- return NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
+ return NET_SockaddrToInetAddress(env, &sa, &port);
}
JNIEXPORT jint JNICALL
--- a/jdk/src/java.base/windows/native/libnio/ch/ServerSocketChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnio/ch/ServerSocketChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -95,7 +95,7 @@
int addrlen = sizeof(sa);
memset((char *)&sa, 0, sizeof(sa));
- newfd = (jint)accept(ssfd, (struct sockaddr *)&sa, &addrlen);
+ newfd = (jint)accept(ssfd, &sa.sa, &addrlen);
if (newfd == INVALID_SOCKET) {
int theErr = (jint)WSAGetLastError();
if (theErr == WSAEWOULDBLOCK) {
@@ -107,7 +107,7 @@
SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
(*env)->SetIntField(env, newfdo, fd_fdID, newfd);
- remote_ia = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, (int *)&remote_port);
+ remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
--- a/jdk/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -88,26 +88,21 @@
Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_connect0(JNIEnv* env, jclass this,
jlong socket, jboolean preferIPv6, jobject iao, jint port, jlong ov)
{
- SOCKET s = (SOCKET) jlong_to_ptr(socket);
- OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
+ SOCKET s = (SOCKET)jlong_to_ptr(socket);
+ OVERLAPPED *lpOverlapped = (OVERLAPPED *)jlong_to_ptr(ov);
SOCKETADDRESS sa;
- int sa_len;
+ int sa_len = 0;
BOOL res;
- if (NET_InetAddressToSockaddr(env, iao, port, (struct sockaddr *)&sa, &sa_len, preferIPv6) != 0) {
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
+ preferIPv6) != 0) {
return IOS_THROWN;
}
ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
- res = (*ConnectEx_func)(s,
- (struct sockaddr *)&sa,
- sa_len,
- NULL,
- 0,
- NULL,
- lpOverlapped);
+ res = (*ConnectEx_func)(s, &sa.sa, sa_len, NULL, 0, NULL, lpOverlapped);
if (res == 0) {
int error = GetLastError();
if (error == ERROR_IO_PENDING) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Tue Jan 24 00:30:23 2017 +0100
@@ -231,6 +231,7 @@
private boolean isFullScreenAnimationOn;
private volatile boolean isInFullScreen;
+ private volatile boolean isIconifyAnimationActive;
private Window target;
private LWWindowPeer peer;
@@ -997,6 +998,9 @@
if (peer != null) {
peer.notifyIconify(iconify);
}
+ if (iconify) {
+ isIconifyAnimationActive = false;
+ }
}
private void deliverZoom(final boolean isZoomed) {
@@ -1071,6 +1075,17 @@
return true;
}
+ private boolean isIconified() {
+ boolean isIconified = false;
+ if (target instanceof Frame) {
+ int state = ((Frame)target).getExtendedState();
+ if ((state & Frame.ICONIFIED) != 0) {
+ isIconified = true;
+ }
+ }
+ return isIconifyAnimationActive || isIconified;
+ }
+
private boolean isOneOfOwnersOrSelf(CPlatformWindow window) {
while (window != null) {
if (this == window) {
@@ -1094,11 +1109,14 @@
// the windows are ordered above their nearest owner; ancestors of the window,
// which is going to become 'main window', are placed above their siblings.
CPlatformWindow rootOwner = getRootOwner();
- if (rootOwner.isVisible()) {
+ if (rootOwner.isVisible() && !rootOwner.isIconified()) {
CWrapper.NSWindow.orderFront(rootOwner.getNSWindowPtr());
}
- final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
- orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target));
+ // Do not order child windows of iconified owner.
+ if (!rootOwner.isIconified()) {
+ final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
+ orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target));
+ }
}
private void orderAboveSiblingsImpl(Window[] windows) {
@@ -1109,10 +1127,12 @@
// Go through the list of windows and perform ordering.
for (Window w : windows) {
+ boolean iconified = false;
final Object p = componentAccessor.getPeer(w);
if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
- if (pw != null && pw.isVisible()) {
+ iconified = isIconified();
+ if (pw != null && pw.isVisible() && !iconified) {
// If the window is one of ancestors of 'main window' or is going to become main by itself,
// the window should be ordered above its siblings; otherwise the window is just ordered
// above its nearest parent.
@@ -1125,10 +1145,13 @@
pw.applyWindowLevel(w);
}
}
- // Retrieve the child windows for each window from the list and store them for future use.
+ // Retrieve the child windows for each window from the list except iconified ones
+ // and store them for future use.
// Note: we collect data about child windows even for invisible owners, since they may have
// visible children.
- childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w)));
+ if (!iconified) {
+ childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w)));
+ }
}
// If some windows, which have just been ordered, have any child windows, let's start new iteration
// and order these child windows.
@@ -1149,6 +1172,10 @@
// NATIVE CALLBACKS
// ----------------------------------------------------------------------
+ private void windowWillMiniaturize() {
+ isIconifyAnimationActive = true;
+ }
+
private void windowDidBecomeMain() {
if (checkBlockingAndOrder()) return;
// If it's not blocked, make sure it's above its siblings
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Tue Jan 24 00:30:23 2017 +0100
@@ -327,10 +327,43 @@
return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
}
+// Retrieves the list of possible window layers (levels)
++ (NSArray*) getWindowLayers {
+ static NSArray *windowLayers;
+ static dispatch_once_t token;
+
+ // Initialize the list of possible window layers
+ dispatch_once(&token, ^{
+ // The layers are ordered from front to back, (i.e. the toppest one is the first)
+ windowLayers = [NSArray arrayWithObjects:
+ [NSNumber numberWithInt:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)],
+ [NSNumber numberWithInt:CGWindowLevelForKey(kCGFloatingWindowLevelKey)],
+ [NSNumber numberWithInt:CGWindowLevelForKey(kCGNormalWindowLevelKey)],
+ nil
+ ];
+ [windowLayers retain];
+ });
+ return windowLayers;
+}
+
// returns id for the topmost window under mouse
+ (NSInteger) getTopmostWindowUnderMouseID {
NSInteger result = -1;
+ NSArray *windowLayers = [AWTWindow getWindowLayers];
+ // Looking for the window under mouse starting from the toppest layer
+ for (NSNumber *layer in windowLayers) {
+ result = [AWTWindow getTopmostWindowUnderMouseIDImpl:[layer integerValue]];
+ if (result != -1) {
+ break;
+ }
+ }
+ return result;
+}
+
++ (NSInteger) getTopmostWindowUnderMouseIDImpl:(NSInteger)windowLayer {
+ NSInteger result = -1;
+
NSRect screenRect = [[NSScreen mainScreen] frame];
NSPoint nsMouseLocation = [NSEvent mouseLocation];
CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
@@ -339,7 +372,7 @@
for (NSDictionary *window in windows) {
NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
- if (layer == 0) {
+ if (layer == windowLayer) {
CGRect rect;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
if (CGRectContainsPoint(rect, cgMouseLocation)) {
@@ -639,6 +672,14 @@
AWT_ASSERT_APPKIT_THREAD;
self.isMinimizing = YES;
+
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
+ if (platformWindow != NULL) {
+ static JNF_MEMBER_CACHE(jm_windowWillMiniaturize, jc_CPlatformWindow, "windowWillMiniaturize", "()V");
+ JNFCallVoidMethod(env, platformWindow, jm_windowWillMiniaturize);
+ (*env)->DeleteLocalRef(env, platformWindow);
+ }
// Excplicitly make myself a key window to avoid possible
// negative visual effects during iconify operation
[self.nsWindow makeKeyAndOrderFront:self.nsWindow];
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageReader.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -730,18 +730,47 @@
// to use it if the data layout is component type.
if (iccProfileField != null
&& itsRaw.getColorModel() instanceof ComponentColorModel) {
- // Create a ColorSpace from the profile.
- byte[] iccProfileValue = iccProfileField.getAsBytes();
- ICC_Profile iccProfile
- = ICC_Profile.getInstance(iccProfileValue);
- ICC_ColorSpace iccColorSpace
- = new ICC_ColorSpace(iccProfile);
-
// Get the raw sample and color information.
ColorModel cmRaw = itsRaw.getColorModel();
ColorSpace csRaw = cmRaw.getColorSpace();
SampleModel smRaw = itsRaw.getSampleModel();
+ ColorSpace iccColorSpace = null;
+ try {
+ // Create a ColorSpace from the profile.
+ byte[] iccProfileValue = iccProfileField.getAsBytes();
+ ICC_Profile iccProfile
+ = ICC_Profile.getInstance(iccProfileValue);
+ iccColorSpace = new ICC_ColorSpace(iccProfile);
+
+ // Workaround for JDK-8145241: test a conversion and fall
+ // back to a standard ColorSpace if it fails. This
+ // workaround could be removed if JDK-8145241 is fixed.
+ float[] rgb =
+ iccColorSpace.toRGB(new float[] {1.0F, 1.0F, 1.0F});
+ } catch (Exception iccProfileException) {
+ processWarningOccurred("Superseding bad ICC profile: "
+ + iccProfileException.getMessage());
+
+ if (iccColorSpace != null) {
+ switch (iccColorSpace.getType()) {
+ case ColorSpace.TYPE_GRAY:
+ iccColorSpace =
+ ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ break;
+ case ColorSpace.TYPE_RGB:
+ iccColorSpace =
+ ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ break;
+ default:
+ iccColorSpace = csRaw;
+ break;
+ }
+ } else {
+ iccColorSpace = csRaw;
+ }
+ }
+
// Get the number of samples per pixel and the number
// of color components.
int numBands = smRaw.getNumBands();
--- a/jdk/src/java.desktop/share/classes/java/beans/AppletInitializer.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/java/beans/AppletInitializer.java Tue Jan 24 00:30:23 2017 +0100
@@ -30,21 +30,20 @@
import java.beans.beancontext.BeanContext;
/**
- * <p>
* This interface is designed to work in collusion with java.beans.Beans.instantiate.
* The interface is intended to provide mechanism to allow the proper
* initialization of JavaBeans that are also Applets, during their
* instantiation by java.beans.Beans.instantiate().
- * </p>
*
* @see java.beans.Beans#instantiate
*
* @since 1.2
*
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
-
-
-@SuppressWarnings("deprecation")
+@Deprecated(since = "9")
public interface AppletInitializer {
/**
@@ -74,7 +73,6 @@
* @param bCtxt The BeanContext intended for this Applet, or
* null.
*/
-
void initialize(Applet newAppletBean, BeanContext bCtxt);
/**
@@ -86,6 +84,5 @@
*
* @param newApplet The newly instantiated JavaBean
*/
-
void activate(Applet newApplet);
}
--- a/jdk/src/java.desktop/share/classes/java/beans/Beans.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/java/beans/Beans.java Tue Jan 24 00:30:23 2017 +0100
@@ -97,8 +97,10 @@
* @exception IOException if an I/O error occurs.
* @since 1.2
*/
-
- public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext) throws IOException, ClassNotFoundException {
+ @SuppressWarnings("deprecation")
+ public static Object instantiate(ClassLoader cls, String beanName,
+ BeanContext beanContext)
+ throws IOException, ClassNotFoundException {
return Beans.instantiate(cls, beanName, beanContext, null);
}
@@ -153,10 +155,18 @@
* object could not be found.
* @exception IOException if an I/O error occurs.
* @since 1.2
+ *
+ * @deprecated It is recommended to use
+ * {@link #instantiate(ClassLoader, String, BeanContext)},
+ * because the Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
- @SuppressWarnings("deprecation")
- public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext, AppletInitializer initializer)
- throws IOException, ClassNotFoundException {
+ @Deprecated(since = "9")
+ public static Object instantiate(ClassLoader cls, String beanName,
+ BeanContext beanContext,
+ AppletInitializer initializer)
+ throws IOException, ClassNotFoundException {
InputStream ins;
ObjectInputStream oins = null;
@@ -501,7 +511,7 @@
* Package private support class. This provides a default AppletContext
* for beans which are applets.
*/
-@SuppressWarnings("deprecation")
+@Deprecated(since = "9")
class BeansAppletContext implements AppletContext {
Applet target;
Hashtable<URL,Object> imageCache = new Hashtable<>();
@@ -586,7 +596,7 @@
* Package private support class. This provides an AppletStub
* for beans which are applets.
*/
-@SuppressWarnings("deprecation")
+@Deprecated(since = "9")
class BeansAppletStub implements AppletStub {
transient boolean active;
transient Applet target;
--- a/jdk/src/java.desktop/share/classes/javax/swing/PopupFactory.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/PopupFactory.java Tue Jan 24 00:30:23 2017 +0100
@@ -260,6 +260,7 @@
* Obtains the appropriate <code>Popup</code> based on
* <code>popupType</code>.
*/
+ @SuppressWarnings("deprecation")
private Popup getPopup(Component owner, Component contents,
int ownerX, int ownerY, int popupType) {
if (GraphicsEnvironment.isHeadless()) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/RepaintManager.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/RepaintManager.java Tue Jan 24 00:30:23 2017 +0100
@@ -525,8 +525,12 @@
* @param h Height of the region to repaint
* @see JApplet#repaint
* @since 1.6
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
- @SuppressWarnings("deprecation")
+ @Deprecated(since = "9")
public void addDirtyRegion(Applet applet, int x, int y, int w, int h) {
addDirtyRegion0(applet, x, y, w, h);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/TablePrintable.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/TablePrintable.java Tue Jan 24 00:30:23 2017 +0100
@@ -380,6 +380,12 @@
// print the current section of the table
g2d.translate(-clip.x, -clip.y);
g2d.clip(clip);
+
+ // set a property so that BasicTableUI#paint can know JTable printMode
+ // is FIT_WIDTH since TablePrintable.printMode is not accessible from BasicTableUI
+ if (printMode == JTable.PrintMode.FIT_WIDTH) {
+ table.putClientProperty("Table.printMode", JTable.PrintMode.FIT_WIDTH);
+ }
table.print(g2d);
// restore the original transform and clip
@@ -407,8 +413,18 @@
for(int visrow = rMin; visrow < rMax; visrow++) {
rowHeight += table.getRowHeight(visrow);
}
- g2d.drawRect(0, 0, visibleBounds.width, hclip.height + rowHeight);
+ // If PrintMode is FIT_WIDTH, then draw rect for entire column width while
+ // printing irrespective of how many columns are visible in console
+ if (printMode == JTable.PrintMode.FIT_WIDTH) {
+ g2d.drawRect(0, 0, clip.width, hclip.height + rowHeight);
+ } else {
+ g2d.drawRect(0, 0, visibleBounds.width, hclip.height + rowHeight);
+ }
+ // clear the property
+ if (printMode == JTable.PrintMode.FIT_WIDTH) {
+ table.putClientProperty("Table.printMode", null);
+ }
// dispose the graphics copy
g2d.dispose();
@@ -534,5 +550,4 @@
} while (clip.width + colWidth <= pw);
}
-
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java Tue Jan 24 00:30:23 2017 +0100
@@ -1812,12 +1812,12 @@
}
boolean ltr = table.getComponentOrientation().isLeftToRight();
-
+ Point upperLeft, lowerRight;
// compute the visible part of table which needs to be painted
Rectangle visibleBounds = clip.intersection(bounds);
- Point upperLeft = visibleBounds.getLocation();
- Point lowerRight = new Point(visibleBounds.x + visibleBounds.width - 1,
- visibleBounds.y + visibleBounds.height - 1);
+ upperLeft = visibleBounds.getLocation();
+ lowerRight = new Point(visibleBounds.x + visibleBounds.width - 1,
+ visibleBounds.y + visibleBounds.height - 1);
int rMin = table.rowAtPoint(upperLeft);
int rMax = table.rowAtPoint(lowerRight);
@@ -1834,6 +1834,18 @@
rMax = table.getRowCount()-1;
}
+ // For FIT_WIDTH, all columns should be printed irrespective of
+ // how many columns are visible. So, we used clip which is already set to
+ // total col width instead of visible region
+ // Since JTable.PrintMode is not accessible
+ // from here, we aet "Table.printMode" in TablePrintable#print and
+ // access from here.
+ Object printMode = table.getClientProperty("Table.printMode");
+ if ((printMode == JTable.PrintMode.FIT_WIDTH)) {
+ upperLeft = clip.getLocation();
+ lowerRight = new Point(clip.x + clip.width - 1,
+ clip.y + clip.height - 1);
+ }
int cMin = table.columnAtPoint(ltr ? upperLeft : lowerRight);
int cMax = table.columnAtPoint(ltr ? lowerRight : upperLeft);
// This should never happen.
@@ -2018,7 +2030,7 @@
int y = damagedArea.y;
for (int row = rMin; row <= rMax; row++) {
y += table.getRowHeight(row);
- g.drawLine(damagedArea.x, y - 1, tableWidth - 1, y - 1);
+ SwingUtilities2.drawHLine(g, damagedArea.x, tableWidth - 1, y - 1);
}
}
if (table.getShowVerticalLines()) {
@@ -2030,14 +2042,14 @@
for (int column = cMin; column <= cMax; column++) {
int w = cm.getColumn(column).getWidth();
x += w;
- g.drawLine(x - 1, 0, x - 1, tableHeight - 1);
+ SwingUtilities2.drawVLine(g, x - 1, 0, tableHeight - 1);
}
} else {
x = damagedArea.x;
for (int column = cMax; column >= cMin; column--) {
int w = cm.getColumn(column).getWidth();
x += w;
- g.drawLine(x - 1, 0, x - 1, tableHeight - 1);
+ SwingUtilities2.drawVLine(g, x - 1, 0, tableHeight - 1);
}
}
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Tue Jan 24 00:30:23 2017 +0100
@@ -27,10 +27,7 @@
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.font.FontRenderContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import javax.swing.JPasswordField;
-import static javax.swing.text.PlainView.isFPMethodOverriden;
/**
* Implements a View suitable for use in JPasswordField
@@ -332,22 +329,6 @@
static char[] ONE = new char[1];
- private final boolean drawEchoCharacterOverridden;
-
- {
- final Class<?> CLS = getClass();
- final Class<?> INT = Integer.TYPE;
- final Class<?> FP = Float.TYPE;
- final Class<?> CHAR = Character.TYPE;
-
- drawEchoCharacterOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {Graphics.class, INT, INT, CHAR};
- Class<?>[] fpTypes = {Graphics2D.class, FP, FP, CHAR};
- return isFPMethodOverriden("drawEchoCharacter", CLS, intTypes, fpTypes);
- }
- });
- }
+ private final boolean drawEchoCharacterOverridden =
+ getFPMethodOverridden(getClass(), "drawEchoCharacter", FPMethodArgs.GNNC);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Tue Jan 24 00:30:23 2017 +0100
@@ -32,6 +32,8 @@
import java.util.Objects;
import javax.swing.event.*;
import java.lang.reflect.Module;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
/**
* Implements View interface for a simple multi-line text view
@@ -818,10 +820,45 @@
return w;
}
- static boolean isFPMethodOverriden(String method,
- Class<?> cls,
- Class<?>[] intTypes,
- Class<?>[] fpTypes)
+ static boolean getFPMethodOverridden(Class<?> cls, String method,
+ FPMethodArgs methodArgs) {
+ HashMap<FPMethodItem, Boolean> map = null;
+ boolean initialized = methodsOverriddenMapRef != null
+ && (map = methodsOverriddenMapRef.get()) != null;
+
+ if (!initialized) {
+ map = new HashMap<>();
+ methodsOverriddenMapRef = new SoftReference<>(map);
+ }
+
+ FPMethodItem key = new FPMethodItem(cls, method);
+ Boolean isFPMethodOverridden = map.get(key);
+ if (isFPMethodOverridden == null) {
+ isFPMethodOverridden = checkFPMethodOverridden(cls, method, methodArgs);
+ map.put(key, isFPMethodOverridden);
+ }
+ return isFPMethodOverridden;
+ }
+
+ private static boolean checkFPMethodOverridden(final Class<?> className,
+ final String methodName,
+ final FPMethodArgs methodArgs) {
+
+ return AccessController
+ .doPrivileged(new PrivilegedAction<Boolean>() {
+ @Override
+ public Boolean run() {
+ return isFPMethodOverridden(methodName, className,
+ methodArgs.getMethodArguments(false),
+ methodArgs.getMethodArguments(true));
+ }
+ });
+ }
+
+ private static boolean isFPMethodOverridden(String method,
+ Class<?> cls,
+ Class<?>[] intTypes,
+ Class<?>[] fpTypes)
{
Module thisModule = PlainView.class.getModule();
while (!thisModule.equals(cls.getModule())) {
@@ -840,6 +877,57 @@
return true;
}
+ enum FPMethodArgs {
+
+ IGNN,
+ IIGNN,
+ GNNII,
+ GNNC;
+
+ public Class<?>[] getMethodArguments(boolean isFPType) {
+ Class<?> N = (isFPType) ? Float.TYPE : Integer.TYPE;
+ Class<?> G = (isFPType) ? Graphics2D.class : Graphics.class;
+ switch (this) {
+ case IGNN:
+ return new Class<?>[]{Integer.TYPE, G, N, N};
+ case IIGNN:
+ return new Class<?>[]{Integer.TYPE, Integer.TYPE, G, N, N};
+ case GNNII:
+ return new Class<?>[]{G, N, N, Integer.TYPE, Integer.TYPE};
+ case GNNC:
+ return new Class<?>[]{G, N, N, Character.TYPE};
+ default:
+ throw new RuntimeException("Unknown method arguments!");
+ }
+ }
+ }
+
+ private static class FPMethodItem {
+
+ final Class<?> className;
+ final String methodName;
+
+ public FPMethodItem(Class<?> className, String methodName) {
+ this.className = className;
+ this.methodName = methodName;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof FPMethodItem) {
+ FPMethodItem that = (FPMethodItem) obj;
+ return this.className.equals(that.className)
+ && this.methodName.equals(that.methodName);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * methodName.hashCode() + className.hashCode();
+ }
+ }
+
// --- member variables -----------------------------------------------
/**
@@ -878,46 +966,13 @@
*/
int firstLineOffset;
- final boolean drawLineOverridden;
- final boolean drawSelectedTextOverridden;
- final boolean drawUnselectedTextOverridden;
- final boolean useFloatingPointAPI;
-
- {
- final Class<?> CLS = getClass();
- final Class<?> INT = Integer.TYPE;
- final Class<?> FP = Float.TYPE;
-
- drawLineOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {INT, Graphics.class, INT, INT};
- Class<?>[] fpTypes = {INT, Graphics2D.class, FP, FP};
- return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
- }
- });
-
- drawUnselectedTextOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
- Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
- return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
- }
- });
-
- drawSelectedTextOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
- Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
- return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
- }
- });
-
- useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
- }
+ private static SoftReference<HashMap<FPMethodItem, Boolean>> methodsOverriddenMapRef;
+ final boolean drawLineOverridden =
+ getFPMethodOverridden(getClass(), "drawLine", FPMethodArgs.IGNN);
+ final boolean drawSelectedTextOverridden =
+ getFPMethodOverridden(getClass(), "drawSelectedText", FPMethodArgs.GNNII);
+ final boolean drawUnselectedTextOverridden =
+ getFPMethodOverridden(getClass(), "drawUnselectedText", FPMethodArgs.GNNII);
+ final boolean useFloatingPointAPI =
+ drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Tue Jan 24 00:30:23 2017 +0100
@@ -28,10 +28,9 @@
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.lang.ref.SoftReference;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import javax.swing.event.*;
-import static javax.swing.text.PlainView.isFPMethodOverriden;
+import static javax.swing.text.PlainView.FPMethodArgs.*;
+import static javax.swing.text.PlainView.getFPMethodOverridden;
/**
* View of plain text (text with only one font and color)
@@ -989,46 +988,12 @@
SoftReference<int[]> lineCache = null;
}
- private final boolean drawLineOverridden;
- private final boolean drawSelectedTextOverridden;
- private final boolean drawUnselectedTextOverridden;
- private final boolean useFloatingPointAPI;
-
- {
- final Class<?> CLS = getClass();
- final Class<?> INT = Integer.TYPE;
- final Class<?> FP = Float.TYPE;
-
- drawLineOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {INT, INT, Graphics.class, INT, INT};
- Class<?>[] fpTypes = {INT, INT, Graphics2D.class, FP, FP};
- return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
- }
- });
-
- drawUnselectedTextOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
- Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
- return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
- }
- });
-
- drawSelectedTextOverridden = AccessController
- .doPrivileged(new PrivilegedAction<Boolean>() {
- @Override
- public Boolean run() {
- Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
- Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
- return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
- }
- });
-
- useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
- }
+ private final boolean drawLineOverridden =
+ getFPMethodOverridden(getClass(), "drawLine", IIGNN);
+ private final boolean drawSelectedTextOverridden =
+ getFPMethodOverridden(getClass(), "drawSelectedText", GNNII);
+ private final boolean drawUnselectedTextOverridden =
+ getFPMethodOverridden(getClass(), "drawUnselectedText", GNNII);
+ private final boolean useFloatingPointAPI =
+ drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletEvent.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletEvent.java Tue Jan 24 00:30:23 2017 +0100
@@ -32,8 +32,13 @@
* AppletEvent class.
*
* @author Sunita Mani
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
@SuppressWarnings("serial") // JDK-implementation class
+@Deprecated(since = "9")
public class AppletEvent extends EventObject {
private Object arg;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletEventMulticaster.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletEventMulticaster.java Tue Jan 24 00:30:23 2017 +0100
@@ -36,7 +36,12 @@
* responsible for dispatching events to them.
*
* @author Sunita Mani
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
+@Deprecated(since = "9")
public class AppletEventMulticaster implements AppletListener {
private final AppletListener a, b;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletIOException.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletIOException.java Tue Jan 24 00:30:23 2017 +0100
@@ -31,10 +31,14 @@
* An applet IO exception.
*
* @author Koji Uno
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
@SuppressWarnings("serial") // JDK implementation class
-public
-class AppletIOException extends IOException {
+@Deprecated(since = "9")
+public class AppletIOException extends IOException {
private String key = null;
private Object msgobj = null;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletIllegalArgumentException.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletIllegalArgumentException.java Tue Jan 24 00:30:23 2017 +0100
@@ -29,10 +29,14 @@
* An applet security exception.
*
* @author Arthur van Hoff
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
@SuppressWarnings("serial") // JDK implementation class
-public
-class AppletIllegalArgumentException extends IllegalArgumentException {
+@Deprecated(since = "9")
+public class AppletIllegalArgumentException extends IllegalArgumentException {
private String key = null;
public AppletIllegalArgumentException(String key) {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletImageRef.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletImageRef.java Tue Jan 24 00:30:23 2017 +0100
@@ -31,6 +31,7 @@
import sun.awt.image.URLImageSource;
import java.net.URL;
+@Deprecated(since = "9")
class AppletImageRef {
private SoftReference<Image> soft = null;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletListener.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletListener.java Tue Jan 24 00:30:23 2017 +0100
@@ -32,8 +32,12 @@
* by objects interested in AppletEvents.
*
* @author Sunita Mani
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
-
+@Deprecated(since = "9")
public interface AppletListener extends EventListener {
public void appletStateChanged(AppletEvent e);
}
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletObjectInputStream.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletObjectInputStream.java Tue Jan 24 00:30:23 2017 +0100
@@ -34,8 +34,12 @@
/**
* This subclass of ObjectInputStream delegates loading of classes to
* an existing ClassLoader.
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
-
+@Deprecated(since = "9")
class AppletObjectInputStream extends ObjectInputStream
{
private AppletClassLoader loader;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Tue Jan 24 00:30:23 2017 +0100
@@ -52,9 +52,14 @@
* thread group to call the applet's init(), start(), stop(), and
* destroy() methods.
*
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
+ *
* @author Arthur van Hoff
*/
-@SuppressWarnings({"serial", "deprecation"}) // JDK implementation class
+@SuppressWarnings({"serial"}) // JDK implementation class
+@Deprecated(since = "9")
public
abstract class AppletPanel extends Panel implements AppletStub, Runnable {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletProps.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletProps.java Tue Jan 24 00:30:23 2017 +0100
@@ -36,6 +36,7 @@
import sun.security.action.*;
@SuppressWarnings("serial") // JDK implementation class
+@Deprecated(since = "9")
class AppletProps extends Frame {
TextField proxyHost;
@@ -197,6 +198,7 @@
/* 4066432 */
/* Dialog class to display property-related errors to user */
@SuppressWarnings("serial") // JDK implementation class
+@Deprecated(since = "9")
class AppletPropsErrorDialog extends Dialog {
@SuppressWarnings("deprecation")
public AppletPropsErrorDialog(Frame parent, String title, String message,
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java Tue Jan 24 00:30:23 2017 +0100
@@ -43,6 +43,7 @@
* A frame to show the applet tag in.
*/
@SuppressWarnings("serial") // JDK-implementation class
+@Deprecated(since = "9")
final class TextFrame extends Frame {
/**
@@ -91,6 +92,7 @@
/**
* Lets us construct one using unix-style one shot behaviors.
*/
+@Deprecated(since = "9")
final class StdAppletViewerFactory implements AppletViewerFactory {
@Override
@@ -116,8 +118,13 @@
* <a href="../../../docs/tooldocs/appletviewertags.html">AppletViewer Tags</a>.
* (The document named appletviewertags.html in the JDK's docs/tooldocs directory,
* once the JDK docs have been installed.)
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
-@SuppressWarnings({"serial", "deprecation"}) // JDK-implementation class
+@SuppressWarnings({"serial"}) // JDK-implementation class
+@Deprecated(since = "9")
public class AppletViewer extends Frame implements AppletContext, Printable {
/**
@@ -146,7 +153,7 @@
*/
AppletViewerFactory factory;
-
+ @Deprecated(since = "9")
private final class UserActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent evt) {
@@ -219,6 +226,7 @@
}
};
+ @Deprecated(since = "9")
class AppletEventListener implements AppletListener
{
final Frame frame;
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewerFactory.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewerFactory.java Tue Jan 24 00:30:23 2017 +0100
@@ -33,8 +33,8 @@
import java.net.URL;
import java.awt.MenuBar;
-public
-interface AppletViewerFactory {
+@Deprecated(since = "9")
+public interface AppletViewerFactory {
public AppletViewer createAppletViewer(int x, int y, URL doc,
Hashtable<String, String> atts);
public MenuBar getBaseMenuBar();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewerPanel.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewerPanel.java Tue Jan 24 00:30:23 2017 +0100
@@ -40,7 +40,12 @@
* destroy() methods.
*
* @author Arthur van Hoff
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
+@Deprecated(since = "9")
class AppletViewerPanel extends AppletPanel {
/* Are we debugging? */
--- a/jdk/src/java.desktop/share/classes/sun/applet/Main.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/applet/Main.java Tue Jan 24 00:30:23 2017 +0100
@@ -39,7 +39,12 @@
/**
* The main entry point into AppletViewer.
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
+@Deprecated(since = "9")
public class Main {
/**
* The file which contains all of the AppletViewer specific properties.
--- a/jdk/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java Tue Jan 24 00:30:23 2017 +0100
@@ -496,10 +496,14 @@
* Checks if the component is in an EmbeddedFrame. If so,
* returns the applet found in the hierarchy or null if
* not found.
- * @return the parent applet or {@ null}
+ * @return the parent applet or {@code null}
* @since 1.6
+ *
+ * @deprecated The Applet API is deprecated. See the
+ * <a href="../../java/applet/package-summary.html"> java.applet package
+ * documentation</a> for further information.
*/
- @SuppressWarnings("deprecation")
+ @Deprecated(since = "9")
public static Applet getAppletIfAncestorOf(Component comp) {
Container parent = comp.getParent();
Applet applet = null;
--- a/jdk/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/native/libawt/awt/medialib/awt_ImagingLib.c Tue Jan 24 00:30:23 2017 +0100
@@ -2419,7 +2419,7 @@
case sun_awt_image_IntegerComponentRaster_TYPE_INT_8BIT_SAMPLES:
if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 4)) &&
SAFE_TO_ALLOC_2(width, 4) &&
- SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 4)))
+ SAFE_TO_ALLOC_3(rasterP->scanlineStride, height, 4)))
{
return -1;
}
@@ -2428,7 +2428,7 @@
if (offset < 0 || offset >= dataSize ||
width > rasterP->scanlineStride ||
- height * rasterP->scanlineStride * 4 > dataSize - offset)
+ ((width + (height - 1) * rasterP->scanlineStride) * 4) > dataSize - offset)
{
// raster data buffer is too short
return -1;
@@ -2446,7 +2446,7 @@
return 0;
case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_SAMPLES:
if (!(SAFE_TO_ALLOC_2(width, rasterP->numBands) &&
- SAFE_TO_ALLOC_2(height, rasterP->scanlineStride)))
+ SAFE_TO_ALLOC_2(rasterP->scanlineStride, height)))
{
return -1;
}
@@ -2455,7 +2455,8 @@
if (offset < 0 || offset >= dataSize ||
width * rasterP->numBands > rasterP->scanlineStride ||
- height * rasterP->scanlineStride > dataSize - offset)
+ ((width * rasterP->numBands) +
+ (height - 1) * rasterP->scanlineStride) > dataSize - offset)
{
// raster data buffer is too short
return -1;
@@ -2474,7 +2475,7 @@
case sun_awt_image_IntegerComponentRaster_TYPE_USHORT_SAMPLES:
if (!((rasterP->chanOffsets[0] == 0 || SAFE_TO_ALLOC_2(rasterP->chanOffsets[0], 2)) &&
SAFE_TO_ALLOC_3(width, rasterP->numBands, 2) &&
- SAFE_TO_ALLOC_3(height, rasterP->scanlineStride, 2)))
+ SAFE_TO_ALLOC_3(rasterP->scanlineStride, height, 2)))
{
return -1;
}
@@ -2483,7 +2484,8 @@
if (offset < 0 || offset >= dataSize ||
width * rasterP->numBands > rasterP->scanlineStride ||
- height * rasterP->scanlineStride * 2 > dataSize - offset)
+ (((width * rasterP->numBands) +
+ (height - 1) * rasterP->scanlineStride)) * 2 > dataSize - offset)
{
// raster data buffer is too short
return -1;
--- a/jdk/src/java.desktop/share/native/libmlib_image/safe_alloc.h Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/share/native/libmlib_image/safe_alloc.h Tue Jan 24 00:30:23 2017 +0100
@@ -35,10 +35,10 @@
*/
#define SAFE_TO_ALLOC_2(c, sz) \
(((c) > 0) && ((sz) > 0) && \
- ((0xffffffffu / ((juint)(c))) > ((juint)(sz))))
+ ((0x7fffffff / (c)) > (sz)))
#define SAFE_TO_ALLOC_3(w, h, sz) \
(((w) > 0) && ((h) > 0) && ((sz) > 0) && \
- (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
+ (((0x7fffffff / (w)) / (h)) > (sz)))
#endif // __SAFE_ALLOC_H__
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Tue Jan 24 00:30:23 2017 +0100
@@ -51,9 +51,9 @@
boolean insets_corrected;
XIconWindow iconWindow;
- WindowDimensions dimensions;
+ volatile WindowDimensions dimensions;
XContentWindow content;
- Insets currentInsets;
+ volatile Insets currentInsets;
XFocusProxyWindow focusProxy;
static final Map<Class<?>,Insets> lastKnownInsets =
Collections.synchronizedMap(new HashMap<>());
@@ -106,7 +106,7 @@
// The lines that follow need to be in a postInit, so they
// happen after the X window is created.
- initResizability();
+ setResizable(winAttr.initialResizability);
XWM.requestWMExtents(getWindow());
content = XContentWindow.createContent(this);
@@ -130,7 +130,12 @@
public void updateMinimumSize() {
super.updateMinimumSize();
- updateMinSizeHints();
+ XToolkit.awtLock();
+ try {
+ updateMinSizeHints();
+ } finally {
+ XToolkit.awtUnlock();
+ }
}
private void updateMinSizeHints() {
@@ -193,8 +198,13 @@
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Title is " + title);
}
- winAttr.title = title;
- updateWMName();
+ XToolkit.awtLock();
+ try {
+ winAttr.title = title;
+ updateWMName();
+ } finally {
+ XToolkit.awtUnlock();
+ }
}
protected String getWMName() {
@@ -206,10 +216,10 @@
}
void updateWMName() {
- super.updateWMName();
- String name = getWMName();
XToolkit.awtLock();
try {
+ super.updateWMName();
+ String name = getWMName();
if (name == null || name.trim().equals("")) {
name = "Java";
}
@@ -304,6 +314,8 @@
if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
currentInsets = new Insets(0, 0, 0, 0);
wm_set_insets = null;
+ } else {
+ insets_corrected = false;
}
}
@@ -330,7 +342,7 @@
if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
getWMSetInsets(XAtom.get(ev.get_atom()));
} else {
- if(!isReparented()) {
+ if (!isReparented()) {
return;
}
wm_set_insets = null;
@@ -377,137 +389,127 @@
insLog.fine(xe.toString());
}
reparent_serial = xe.get_serial();
- XToolkit.awtLock();
- try {
- long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
+ long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
+
+ if (isEmbedded()) {
+ setReparented(true);
+ insets_corrected = true;
+ return;
+ }
+ if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
+ setReparented(true);
+ insets_corrected = true;
+ reshape(dimensions, SET_SIZE, false);
+ } else if (xe.get_parent() == root) {
+ configure_seen = false;
+ insets_corrected = false;
- if (isEmbedded()) {
- setReparented(true);
- insets_corrected = true;
+ /*
+ * We can be repareted to root for two reasons:
+ * . setVisible(false)
+ * . WM exited
+ */
+ if (isVisible()) { /* WM exited */
+ /* Work around 4775545 */
+ XWM.getWM().unshadeKludge(this);
+ insLog.fine("- WM exited");
+ } else {
+ insLog.fine(" - reparent due to hide");
+ }
+ } else { /* reparented to WM frame, figure out our insets */
+ setReparented(true);
+ insets_corrected = false;
+ if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
return;
}
- Component t = target;
- if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
- setReparented(true);
- insets_corrected = true;
- reshape(dimensions, SET_SIZE, false);
- } else if (xe.get_parent() == root) {
- configure_seen = false;
- insets_corrected = false;
- /*
- * We can be repareted to root for two reasons:
- * . setVisible(false)
- * . WM exited
- */
- if (isVisible()) { /* WM exited */
- /* Work around 4775545 */
- XWM.getWM().unshadeKludge(this);
- insLog.fine("- WM exited");
- } else {
- insLog.fine(" - reparent due to hide");
+ // Check if we have insets provided by the WM
+ Insets correctWM = getWMSetInsets(null);
+ if (correctWM != null) {
+ if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
+ insLog.finer("wm-provided insets {0}", correctWM);
}
- } else { /* reparented to WM frame, figure out our insets */
- setReparented(true);
- insets_corrected = false;
- if (XWM.getWMID() == XWM.UNITY_COMPIZ_WM) {
+ // If these insets are equal to our current insets - no actions are necessary
+ Insets dimInsets = dimensions.getInsets();
+ if (correctWM.equals(dimInsets)) {
+ insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
+ no_reparent_artifacts = true;
+ insets_corrected = true;
+ applyGuessedInsets();
return;
}
+ } else {
+ correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
+ if (correctWM != null) {
+ correctWM = copyAndScaleDown(correctWM);
+ }
- // Check if we have insets provided by the WM
- Insets correctWM = getWMSetInsets(null);
- if (correctWM != null) {
- if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
- insLog.finer("wm-provided insets {0}", correctWM);
- }
- // If these insets are equal to our current insets - no actions are necessary
- Insets dimInsets = dimensions.getInsets();
- if (correctWM.equals(dimInsets)) {
- insLog.finer("Insets are the same as estimated - no additional reshapes necessary");
- no_reparent_artifacts = true;
- insets_corrected = true;
- applyGuessedInsets();
- return;
- }
- } else {
- correctWM = XWM.getWM().getInsets(this, xe.get_window(), xe.get_parent());
+ if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
if (correctWM != null) {
- correctWM = copyAndScaleDown(correctWM);
- }
-
- if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
- if (correctWM != null) {
- insLog.finer("correctWM {0}", correctWM);
- } else {
- insLog.finer("correctWM insets are not available, waiting for configureNotify");
- }
+ insLog.finer("correctWM {0}", correctWM);
+ } else {
+ insLog.finer("correctWM insets are not available, waiting for configureNotify");
}
}
+ }
- if (correctWM != null) {
- handleCorrectInsets(correctWM);
- }
+ if (correctWM != null) {
+ handleCorrectInsets(correctWM);
}
- } finally {
- XToolkit.awtUnlock();
}
}
- protected void handleCorrectInsets(Insets correctWM) {
- XToolkit.awtLock();
- try {
- /*
- * Ok, now see if we need adjust window size because
- * initial insets were wrong (most likely they were).
- */
- Insets correction = difference(correctWM, currentInsets);
- if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
- insLog.finest("Corrention {0}", correction);
- }
- if (!isNull(correction)) {
- currentInsets = copy(correctWM);
- applyGuessedInsets();
+ private void handleCorrectInsets(Insets correctWM) {
+ /*
+ * Ok, now see if we need adjust window size because
+ * initial insets were wrong (most likely they were).
+ */
+ Insets correction = difference(correctWM, currentInsets);
+ if (insLog.isLoggable(PlatformLogger.Level.FINEST)) {
+ insLog.finest("Corrention {0}", correction);
+ }
+ if (!isNull(correction)) {
+ currentInsets = copy(correctWM);
+ applyGuessedInsets();
- //Fix for 6318109: PIT: Min Size is not honored properly when a
- //smaller size is specified in setSize(), XToolkit
- //update minimum size hints
- updateMinSizeHints();
- }
- if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
- insLog.finer("Dimensions before reparent: " + dimensions);
- }
-
- dimensions.setInsets(getRealInsets());
- insets_corrected = true;
+ //Fix for 6318109: PIT: Min Size is not honored properly when a
+ //smaller size is specified in setSize(), XToolkit
+ //update minimum size hints
+ updateMinSizeHints();
+ }
+ if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
+ insLog.finer("Dimensions before reparent: " + dimensions);
+ }
+ WindowDimensions newDimensions = new WindowDimensions(dimensions);
+ newDimensions.setInsets(getRealInsets());
+ dimensions = newDimensions;
+ insets_corrected = true;
- if (isMaximized()) {
- return;
- }
+ if (isMaximized()) {
+ return;
+ }
- /*
- * If this window has been sized by a pack() we need
- * to keep the interior geometry intact. Since pack()
- * computed width and height with wrong insets, we
- * must adjust the target dimensions appropriately.
- */
- if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
- reshape(dimensions, SET_BOUNDS, false);
- } else {
- reshape(dimensions, SET_SIZE, false);
- }
- } finally {
- XToolkit.awtUnlock();
+ /*
+ * If this window has been sized by a pack() we need
+ * to keep the interior geometry intact. Since pack()
+ * computed width and height with wrong insets, we
+ * must adjust the target dimensions appropriately.
+ */
+ if ((getHints().get_flags() & (XUtilConstants.USPosition | XUtilConstants.PPosition)) != 0) {
+ reshape(dimensions, SET_BOUNDS, false);
+ } else {
+ reshape(dimensions, SET_SIZE, false);
}
}
- public void handleMoved(WindowDimensions dims) {
+ void handleMoved(WindowDimensions dims) {
Point loc = dims.getLocation();
AWTAccessor.getComponentAccessor().setLocation(target, loc.x, loc.y);
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
}
- protected Insets guessInsets() {
+ private Insets guessInsets() {
if (isEmbedded() || isTargetUndecorated()) {
return new Insets(0, 0, 0, 0);
} else {
@@ -532,16 +534,7 @@
currentInsets = copy(guessed);
}
- public void revalidate() {
- XToolkit.executeOnEventHandlerThread(target, new Runnable() {
- public void run() {
- target.invalidate();
- target.validate();
- }
- });
- }
-
- Insets getRealInsets() {
+ private Insets getRealInsets() {
if (isNull(currentInsets)) {
applyGuessedInsets();
}
@@ -578,7 +571,7 @@
// Coordinates are that of the target
// Called only on Toolkit thread
- public void reshape(WindowDimensions newDimensions, int op,
+ private void reshape(WindowDimensions newDimensions, int op,
boolean userReshape)
{
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
@@ -599,81 +592,75 @@
}
newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
}
- XToolkit.awtLock();
- try {
- if (!isReparented() || !isVisible()) {
- if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
- insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
- Boolean.valueOf(isReparented()), Boolean.valueOf(visible));
- }
-
- // Fix for 6323293.
- // This actually is needed to preserve compatibility with previous releases -
- // some of licensees are expecting componentMoved event on invisible one while
- // its location changes.
- Point oldLocation = getLocation();
+ if (!isReparented() || !isVisible()) {
+ if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
+ insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
+ Boolean.valueOf(isReparented()), Boolean.valueOf(visible));
+ }
- Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX(target),
- AWTAccessor.getComponentAccessor().getY(target));
-
- if (!newLocation.equals(oldLocation)) {
- handleMoved(newDimensions);
- }
+ // Fix for 6323293.
+ // This actually is needed to preserve compatibility with previous releases -
+ // some of licensees are expecting componentMoved event on invisible one while
+ // its location changes.
+ Point oldLocation = getLocation();
- dimensions = new WindowDimensions(newDimensions);
- updateSizeHints(dimensions);
- Rectangle client = dimensions.getClientRect();
- checkShellRect(client);
- setShellBounds(client);
- if (content != null &&
- !content.getSize().equals(newDimensions.getSize()))
- {
- reconfigureContentWindow(newDimensions);
- }
- return;
+ Point newLocation = new Point(AWTAccessor.getComponentAccessor().getX(target),
+ AWTAccessor.getComponentAccessor().getY(target));
+
+ if (!newLocation.equals(oldLocation)) {
+ handleMoved(newDimensions);
}
- int wm = XWM.getWMID();
- updateChildrenSizes();
- applyGuessedInsets();
-
- Rectangle shellRect = newDimensions.getClientRect();
-
- if (gravityBug()) {
- Insets in = newDimensions.getInsets();
- shellRect.translate(in.left, in.top);
+ dimensions = new WindowDimensions(newDimensions);
+ updateSizeHints(dimensions);
+ Rectangle client = dimensions.getClientRect();
+ checkShellRect(client);
+ setShellBounds(client);
+ if (content != null &&
+ !content.getSize().equals(newDimensions.getSize()))
+ {
+ reconfigureContentWindow(newDimensions);
}
+ return;
+ }
- if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) {
- shellRect.setLocation(0, 0);
- }
+ updateChildrenSizes();
+ applyGuessedInsets();
- checkShellRectSize(shellRect);
- if (!isEmbedded()) {
- checkShellRectPos(shellRect);
- }
+ Rectangle shellRect = newDimensions.getClientRect();
+
+ if (gravityBug()) {
+ Insets in = newDimensions.getInsets();
+ shellRect.translate(in.left, in.top);
+ }
- op = op & ~NO_EMBEDDED_CHECK;
+ if ((op & NO_EMBEDDED_CHECK) == 0 && isEmbedded()) {
+ shellRect.setLocation(0, 0);
+ }
- if (op == SET_LOCATION) {
- setShellPosition(shellRect);
- } else if (isResizable()) {
- if (op == SET_BOUNDS) {
- setShellBounds(shellRect);
- } else {
- setShellSize(shellRect);
- }
+ checkShellRectSize(shellRect);
+ if (!isEmbedded()) {
+ checkShellRectPos(shellRect);
+ }
+
+ op = op & ~NO_EMBEDDED_CHECK;
+
+ if (op == SET_LOCATION) {
+ setShellPosition(shellRect);
+ } else if (isResizable()) {
+ if (op == SET_BOUNDS) {
+ setShellBounds(shellRect);
} else {
- XWM.setShellNotResizable(this, newDimensions, shellRect, true);
- if (op == SET_BOUNDS) {
- setShellPosition(shellRect);
- }
+ setShellSize(shellRect);
}
+ } else {
+ XWM.setShellNotResizable(this, newDimensions, shellRect, true);
+ if (op == SET_BOUNDS) {
+ setShellPosition(shellRect);
+ }
+ }
- reconfigureContentWindow(newDimensions);
- } finally {
- XToolkit.awtUnlock();
- }
+ reconfigureContentWindow(newDimensions);
}
/**
@@ -682,8 +669,6 @@
private void reshape(int x, int y, int width, int height, int operation,
boolean userReshape)
{
- Rectangle newRec;
- boolean setClient = false;
WindowDimensions dims = new WindowDimensions(dimensions);
switch (operation & (~NO_EMBEDDED_CHECK)) {
case SET_LOCATION:
@@ -726,7 +711,12 @@
*/
public void setBounds(int x, int y, int width, int height, int op) {
// TODO: Rewrite with WindowDimensions
- reshape(x, y, width, height, op, true);
+ XToolkit.awtLock();
+ try {
+ reshape(x, y, width, height, op, true);
+ } finally {
+ XToolkit.awtUnlock();
+ }
validateSurface();
}
@@ -861,81 +851,74 @@
checkShellRectPos(shellRect);
}
- public void setShellBounds(Rectangle rec) {
+ private void setShellBounds(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell bounds on " + this + " to " + rec);
}
- XToolkit.awtLock();
- try {
- updateSizeHints(rec.x, rec.y, rec.width, rec.height);
- XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getShell(),
- scaleUp(rec.x), scaleUp(rec.y),
- scaleUp(rec.width), scaleUp(rec.height));
- }
- finally {
- XToolkit.awtUnlock();
- }
+ updateSizeHints(rec.x, rec.y, rec.width, rec.height);
+ XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getShell(),
+ scaleUp(rec.x), scaleUp(rec.y),
+ scaleUp(rec.width), scaleUp(rec.height));
}
- public void setShellSize(Rectangle rec) {
+
+ private void setShellSize(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell size on " + this + " to " + rec);
}
- XToolkit.awtLock();
- try {
- updateSizeHints(rec.x, rec.y, rec.width, rec.height);
- XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(),
- scaleUp(rec.width), scaleUp(rec.height));
- }
- finally {
- XToolkit.awtUnlock();
- }
+ updateSizeHints(rec.x, rec.y, rec.width, rec.height);
+ XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(),
+ scaleUp(rec.width), scaleUp(rec.height));
}
- public void setShellPosition(Rectangle rec) {
+
+ private void setShellPosition(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell position on " + this + " to " + rec);
}
- XToolkit.awtLock();
- try {
- updateSizeHints(rec.x, rec.y, rec.width, rec.height);
- XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(),
- scaleUp(rec.x), scaleUp(rec.y));
- }
- finally {
- XToolkit.awtUnlock();
- }
+ updateSizeHints(rec.x, rec.y, rec.width, rec.height);
+ XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(),
+ scaleUp(rec.x), scaleUp(rec.y));
}
- void initResizability() {
- setResizable(winAttr.initialResizability);
- }
public void setResizable(boolean resizable) {
- int fs = winAttr.functions;
- if (!isResizable() && resizable) {
- resetWMSetInsets();
- if (!isEmbedded()) {
- setReparented(false);
- }
- winAttr.isResizable = resizable;
- if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
- fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
- } else {
- fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
+ XToolkit.awtLock();
+ try {
+ int fs = winAttr.functions;
+ if (!isResizable() && resizable) {
+ resetWMSetInsets();
+ if (!isEmbedded()) {
+ setReparented(false);
+ }
+ winAttr.isResizable = resizable;
+ if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
+ fs &= ~(MWMConstants.MWM_FUNC_RESIZE
+ | MWMConstants.MWM_FUNC_MAXIMIZE);
+ } else {
+ fs |= (MWMConstants.MWM_FUNC_RESIZE
+ | MWMConstants.MWM_FUNC_MAXIMIZE);
+ }
+ winAttr.functions = fs;
+ XWM.setShellResizable(this);
+ } else if (isResizable() && !resizable) {
+ resetWMSetInsets();
+ if (!isEmbedded()) {
+ setReparented(false);
+ }
+ winAttr.isResizable = resizable;
+ if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
+ fs |= (MWMConstants.MWM_FUNC_RESIZE
+ | MWMConstants.MWM_FUNC_MAXIMIZE);
+ } else {
+ fs &= ~(MWMConstants.MWM_FUNC_RESIZE
+ | MWMConstants.MWM_FUNC_MAXIMIZE);
+ }
+ winAttr.functions = fs;
+ XWM.setShellNotResizable(this, dimensions,
+ XWM.getWMID() == XWM.UNITY_COMPIZ_WM && configure_seen ?
+ dimensions.getScreenBounds() :
+ dimensions.getBounds(), false);
}
- winAttr.functions = fs;
- XWM.setShellResizable(this);
- } else if (isResizable() && !resizable) {
- resetWMSetInsets();
- if (!isEmbedded()) {
- setReparented(false);
- }
- winAttr.isResizable = resizable;
- if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
- fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
- } else {
- fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE);
- }
- winAttr.functions = fs;
- XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
+ } finally {
+ XToolkit.awtUnlock();
}
}
@@ -990,17 +973,16 @@
try {
if (configure_seen) {
return toGlobal(0,0);
- } else {
- Point location = target.getLocation();
- if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
- insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
- this, location);
- }
- return location;
}
} finally {
XToolkit.awtUnlock();
}
+ Point location = target.getLocation();
+ if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
+ insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
+ this, location);
+ }
+ return location;
}
@@ -1134,7 +1116,7 @@
return focusProxy;
}
- public void handleQuit() {
+ private void handleQuit() {
postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Tue Jan 24 00:30:23 2017 +0100
@@ -1029,8 +1029,14 @@
}
XToolkit.awtLock();
try {
- Rectangle shellBounds = window.getShellBounds();
- shellBounds.translate(-window.currentInsets.left, -window.currentInsets.top);
+ Rectangle shellBounds;
+ if (getWMID() != UNITY_COMPIZ_WM) {
+ shellBounds = window.getShellBounds();
+ shellBounds.translate(-window.currentInsets.left,
+ -window.currentInsets.top);
+ } else {
+ shellBounds = window.getDimensions().getScreenBounds();
+ }
window.updateSizeHints(window.getDimensions());
requestWMExtents(window.getWindow());
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(),
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Tue Jan 24 00:30:23 2017 +0100
@@ -1053,15 +1053,8 @@
// of setting it, it is a safe assumption to just always
// include SheetCollate as supported attribute.
- /*
- In Linux, we use Postscript for rendering but Linux still
- has issues in propagating Postscript-embedded setpagedevice
- setting like collation. Therefore, we temporarily exclude
- Linux.
- */
- if (!PrintServiceLookupProvider.isLinux()) {
- catList.add(SheetCollate.class);
- }
+ catList.add(SheetCollate.class);
+
}
// With the assumption that Chromaticity is equivalent to
--- a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -362,59 +362,81 @@
}
/**
- * Main program to start a registry. <br>
- * The port number can be specified on the command line.
+ * Return a new RegistryImpl on the requested port and export it to serve
+ * registry requests. A classloader is initialized from the system property
+ * "env.class.path" and a security manager is set unless one is already set.
+ * <p>
+ * The returned Registry is fully functional within the current process and
+ * is usable for internal and testing purposes.
+ *
+ * @param regPort port on which the rmiregistry accepts requests;
+ * if 0, an implementation specific port is assigned
+ * @return a RegistryImpl instance
+ * @exception RemoteException If remote operation failed.
+ * @since 9
*/
- public static void main(String args[])
- {
+ public static RegistryImpl createRegistry(int regPort) throws RemoteException {
// Create and install the security manager if one is not installed
// already.
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
+ /*
+ * Fix bugid 4147561: When JDK tools are executed, the value of
+ * the CLASSPATH environment variable for the shell in which they
+ * were invoked is no longer incorporated into the application
+ * class path; CLASSPATH's only effect is to be the value of the
+ * system property "env.class.path". To preserve the previous
+ * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
+ * CLASSPATH should still be considered when resolving classes
+ * being unmarshalled. To effect this old behavior, a class
+ * loader that loads from the file path specified in the
+ * "env.class.path" property is created and set to be the context
+ * class loader before the remote object is exported.
+ */
+ String envcp = System.getProperty("env.class.path");
+ if (envcp == null) {
+ envcp = "."; // preserve old default behavior
+ }
+ URL[] urls = pathToURLs(envcp);
+ ClassLoader cl = new URLClassLoader(urls);
+
+ /*
+ * Fix bugid 4242317: Classes defined by this class loader should
+ * be annotated with the value of the "java.rmi.server.codebase"
+ * property, not the "file:" URLs for the CLASSPATH elements.
+ */
+ sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+
+ Thread.currentThread().setContextClassLoader(cl);
+
+ RegistryImpl registryImpl = null;
try {
- /*
- * Fix bugid 4147561: When JDK tools are executed, the value of
- * the CLASSPATH environment variable for the shell in which they
- * were invoked is no longer incorporated into the application
- * class path; CLASSPATH's only effect is to be the value of the
- * system property "env.class.path". To preserve the previous
- * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
- * CLASSPATH should still be considered when resolving classes
- * being unmarshalled. To effect this old behavior, a class
- * loader that loads from the file path specified in the
- * "env.class.path" property is created and set to be the context
- * class loader before the remote object is exported.
- */
- String envcp = System.getProperty("env.class.path");
- if (envcp == null) {
- envcp = "."; // preserve old default behavior
- }
- URL[] urls = pathToURLs(envcp);
- ClassLoader cl = new URLClassLoader(urls);
+ registryImpl = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<RegistryImpl>() {
+ public RegistryImpl run() throws RemoteException {
+ return new RegistryImpl(regPort);
+ }
+ }, getAccessControlContext(regPort));
+ } catch (PrivilegedActionException ex) {
+ throw (RemoteException) ex.getException();
+ }
- /*
- * Fix bugid 4242317: Classes defined by this class loader should
- * be annotated with the value of the "java.rmi.server.codebase"
- * property, not the "file:" URLs for the CLASSPATH elements.
- */
- sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+ return registryImpl;
+ }
- Thread.currentThread().setContextClassLoader(cl);
-
+ /**
+ * Main program to start a registry. <br>
+ * The port number can be specified on the command line.
+ */
+ public static void main(String args[])
+ {
+ try {
final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
: Registry.REGISTRY_PORT;
- try {
- registry = AccessController.doPrivileged(
- new PrivilegedExceptionAction<RegistryImpl>() {
- public RegistryImpl run() throws RemoteException {
- return new RegistryImpl(regPort);
- }
- }, getAccessControlContext(regPort));
- } catch (PrivilegedActionException ex) {
- throw (RemoteException) ex.getException();
- }
+
+ registry = createRegistry(regPort);
// prevent registry from exiting
while (true) {
--- a/jdk/src/jdk.internal.le/windows/native/lible/WindowsTerminal.cpp Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.internal.le/windows/native/lible/WindowsTerminal.cpp Tue Jan 24 00:30:23 2017 +0100
@@ -102,26 +102,26 @@
JNIEXPORT jint JNICALL Java_jdk_internal_jline_WindowsTerminal_getWindowsTerminalWidth
(JNIEnv *, jobject) {
- HANDLE hStdIn;
- if ((hStdIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
+ HANDLE hStdOut;
+ if ((hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
return -1;
}
CONSOLE_SCREEN_BUFFER_INFO info;
- if (! GetConsoleScreenBufferInfo(hStdIn, &info)) {
+ if (! GetConsoleScreenBufferInfo(hStdOut, &info)) {
return -1;
}
- return info.dwSize.X;
+ return info.srWindow.Right - info.srWindow.Left;
}
JNIEXPORT jint JNICALL Java_jdk_internal_jline_WindowsTerminal_getWindowsTerminalHeight
(JNIEnv *, jobject) {
- HANDLE hStdIn;
- if ((hStdIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
+ HANDLE hStdOut;
+ if ((hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
return -1;
}
CONSOLE_SCREEN_BUFFER_INFO info;
- if (! GetConsoleScreenBufferInfo(hStdIn, &info)) {
+ if (! GetConsoleScreenBufferInfo(hStdOut, &info)) {
return -1;
}
- return info.dwSize.Y;
+ return info.srWindow.Bottom - info.srWindow.Top + 1;
}
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,8 @@
import java.nio.file.Paths;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+
+import jdk.internal.module.ModulePath;
import jdk.internal.module.ModuleResolution;
/**
@@ -155,8 +157,8 @@
for (String dir : dirs) {
paths[i++] = Paths.get(dir);
}
- jartool.moduleFinder = ModuleFinder.compose(jartool.moduleFinder,
- ModuleFinder.of(paths));
+ jartool.moduleFinder =
+ new ModulePath(Runtime.version(), true, paths);
}
},
new Option(false, OptionType.CREATE_UPDATE, "--do-not-resolve-by-default") {
@@ -169,9 +171,9 @@
new Option(true, OptionType.CREATE_UPDATE, "--warn-if-resolved") {
void process(Main jartool, String opt, String arg) throws BadArgs {
ModuleResolution mres = ModuleResolution.empty();
- if (jartool.moduleResolution.doNotResolveByDefault())
+ if (jartool.moduleResolution.doNotResolveByDefault()) {
mres.withDoNotResolveByDefault();
-
+ }
if (arg.equals("deprecated")) {
jartool.moduleResolution = mres.withDeprecated();
} else if (arg.equals("deprecated-for-removal")) {
@@ -201,26 +203,27 @@
// Other options
new Option(true, true, OptionType.OTHER, "--help", "-h") {
void process(Main jartool, String opt, String arg) throws BadArgs {
- if (arg == null) {
- jartool.info = Main.Info.HELP;
- return;
+ if (jartool.info == null) {
+ if (arg == null) {
+ jartool.info = GNUStyleOptions::printHelp; // Main.Info.HELP;
+ return;
+ }
+ if (!arg.equals("compat"))
+ throw new BadArgs("error.illegal.option", arg).showUsage(true);
+ // jartool.info = Main.Info.COMPAT_HELP;
+ jartool.info = GNUStyleOptions::printCompatHelp;
}
-
- if (!arg.equals("compat"))
- throw new BadArgs("error.illegal.option", arg).showUsage(true);
-
- jartool.info = Main.Info.COMPAT_HELP;
}
},
new Option(false, OptionType.OTHER, "--help-extra") {
void process(Main jartool, String opt, String arg) throws BadArgs {
- jartool.info = Main.Info.HELP_EXTRA;
+ jartool.info = GNUStyleOptions::printHelpExtra;
}
},
new Option(false, OptionType.OTHER, "--version") {
void process(Main jartool, String opt, String arg) {
if (jartool.info == null)
- jartool.info = Main.Info.VERSION;
+ jartool.info = GNUStyleOptions::printVersion;
}
}
};
@@ -279,14 +282,14 @@
static int parseOptions(Main jartool, String[] args) throws BadArgs {
int count = 0;
if (args.length == 0) {
- jartool.info = Main.Info.USAGE_TRYHELP;
+ jartool.info = GNUStyleOptions::printUsageTryHelp; // never be here
return 0;
}
// process options
for (; count < args.length; count++) {
- if (args[count].charAt(0) != '-' || args[count].equals("-C")
- || args[count].equals("--release"))
+ if (args[count].charAt(0) != '-' || args[count].equals("-C") ||
+ args[count].equals("--release"))
break;
String name = args[count];
@@ -322,15 +325,15 @@
throw new BadArgs("error.unrecognized.option", name).showUsage(true);
}
- static void printHelp(PrintWriter out) {
- printHelp(out, false);
+ static void printHelpExtra(PrintWriter out) {
+ printHelp0(out, true);
}
- static void printHelpExtra(PrintWriter out) {
- printHelp(out, true);
+ static void printHelp(PrintWriter out) {
+ printHelp0(out, false);
}
- private static void printHelp(PrintWriter out, boolean printExtra) {
+ private static void printHelp0(PrintWriter out, boolean printExtra) {
out.format("%s%n", Main.getMsg("main.help.preopt"));
for (OptionType type : OptionType.values()) {
boolean typeHeadingWritten = false;
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import java.io.*;
import java.lang.module.Configuration;
+import java.lang.module.InvalidModuleDescriptorException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Provides;
@@ -46,7 +47,7 @@
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.function.Consumer;
-import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -58,6 +59,7 @@
import jdk.internal.module.Checks;
import jdk.internal.module.ModuleHashes;
+import jdk.internal.module.ModuleHashesBuilder;
import jdk.internal.module.ModuleInfo;
import jdk.internal.module.ModuleInfoExtender;
import jdk.internal.module.ModuleResolution;
@@ -66,7 +68,6 @@
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toSet;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
@@ -74,58 +75,24 @@
* (Java Archive) file format. The JAR format is based on the ZIP file
* format, with optional meta-information stored in a MANIFEST entry.
*/
-public
-class Main {
+public class Main {
String program;
PrintWriter out, err;
String fname, mname, ename;
String zname = "";
String rootjar = null;
- Set<String> concealedPackages = new HashSet<>(); // used by Validator
private static final int BASE_VERSION = 0;
- class Entry {
- final String basename;
- final String entryname;
+ private static class Entry {
+ final String name;
final File file;
final boolean isDir;
- Entry(File file, String basename, String entryname) {
- this.file = file;
- this.isDir = file.isDirectory();
- this.basename = basename;
- this.entryname = entryname;
- }
-
- Entry(int version, File file) {
+ Entry(File file, String name, boolean isDir) {
this.file = file;
- String path = file.getPath();
- if (file.isDirectory()) {
- isDir = true;
- path = path.endsWith(File.separator) ? path :
- path + File.separator;
- } else {
- isDir = false;
- }
- EntryName en = new EntryName(path, version);
- basename = en.baseName;
- entryname = en.entryName;
- }
-
- /**
- * Returns a new Entry that trims the versions directory.
- *
- * This entry should be a valid entry matching the given version.
- */
- Entry toVersionedEntry(int version) {
- assert isValidVersionedEntry(this, version);
-
- if (version == BASE_VERSION)
- return this;
-
- EntryName en = new EntryName(trimVersionsDir(basename, version), version);
- return new Entry(this.file, en.baseName, en.entryName);
+ this.isDir = isDir;
+ this.name = name;
}
@Override
@@ -141,32 +108,6 @@
}
}
- class EntryName {
- final String baseName;
- final String entryName;
-
- EntryName(String name, int version) {
- name = name.replace(File.separatorChar, '/');
- String matchPath = "";
- for (String path : pathsMap.get(version)) {
- if (name.startsWith(path)
- && (path.length() > matchPath.length())) {
- matchPath = path;
- }
- }
- name = safeName(name.substring(matchPath.length()));
- // the old implementaton doesn't remove
- // "./" if it was led by "/" (?)
- if (name.startsWith("./")) {
- name = name.substring(2);
- }
- baseName = name;
- entryName = (version > BASE_VERSION)
- ? VERSIONS_DIR + version + "/" + baseName
- : baseName;
- }
- }
-
// An entryName(path)->Entry map generated during "expand", it helps to
// decide whether or not an existing entry in a jar file needs to be
// replaced, during the "update" operation.
@@ -175,11 +116,8 @@
// All entries need to be added/updated.
Set<Entry> entries = new LinkedHashSet<>();
- // All packages.
- Set<String> packages = new HashSet<>();
- // All actual entries added, or existing, in the jar file ( excl manifest
- // and module-info.class ). Populated during create or update.
- Set<String> jarEntries = new HashSet<>();
+ // module-info.class entries need to be added/updated.
+ Map<String,byte[]> moduleInfos = new HashMap<>();
// A paths Set for each version, where each Set contains directories
// specified by the "-C" operation.
@@ -208,19 +146,7 @@
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, dflag;
/* To support additional GNU Style informational options */
- enum Info {
- HELP(GNUStyleOptions::printHelp),
- HELP_EXTRA(GNUStyleOptions::printHelpExtra),
- COMPAT_HELP(GNUStyleOptions::printCompatHelp),
- USAGE_TRYHELP(GNUStyleOptions::printUsageTryHelp),
- VERSION(GNUStyleOptions::printVersion);
-
- private Consumer<PrintWriter> printFunction;
- Info(Consumer<PrintWriter> f) { this.printFunction = f; }
- void print(PrintWriter out) { printFunction.accept(out); }
- };
- Info info;
-
+ Consumer<PrintWriter> info;
/* Modular jar related options */
Version moduleVersion;
@@ -228,8 +154,7 @@
ModuleResolution moduleResolution = ModuleResolution.empty();
ModuleFinder moduleFinder = ModuleFinder.of();
- private static final String MODULE_INFO = "module-info.class";
-
+ static final String MODULE_INFO = "module-info.class";
static final String MANIFEST_DIR = "META-INF/";
static final String VERSIONS_DIR = MANIFEST_DIR + "versions/";
static final String VERSION = "1.0";
@@ -324,7 +249,6 @@
}
}
}
-
if (cflag) {
Manifest manifest = null;
if (!Mflag) {
@@ -347,72 +271,60 @@
addMultiRelease(manifest);
}
}
-
- Map<String,Path> moduleInfoPaths = new HashMap<>();
- for (int version : filesMap.keySet()) {
- String[] files = filesMap.get(version);
- expand(null, files, false, moduleInfoPaths, version);
- }
-
- Map<String,byte[]> moduleInfos = new LinkedHashMap<>();
- if (!moduleInfoPaths.isEmpty()) {
- if (!checkModuleInfos(moduleInfoPaths))
- return false;
-
- // root module-info first
- byte[] b = readModuleInfo(moduleInfoPaths.get(MODULE_INFO));
- moduleInfos.put(MODULE_INFO, b);
- for (Map.Entry<String,Path> e : moduleInfoPaths.entrySet())
- moduleInfos.putIfAbsent(e.getKey(), readModuleInfo(e.getValue()));
-
- if (!addExtendedModuleAttributes(moduleInfos))
- return false;
+ expand();
+ if (!moduleInfos.isEmpty()) {
+ // All actual file entries (excl manifest and module-info.class)
+ Set<String> jentries = new HashSet<>();
+ // all packages if it's a class or resource
+ Set<String> packages = new HashSet<>();
+ entries.stream()
+ .filter(e -> !e.isDir)
+ .forEach( e -> {
+ addPackageIfNamed(packages, e.name);
+ jentries.add(e.name);
+ });
+ addExtendedModuleAttributes(moduleInfos, packages);
// Basic consistency checks for modular jars.
- if (!checkServices(moduleInfos.get(MODULE_INFO)))
+ if (!checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries))
return false;
} else if (moduleVersion != null || modulesToHash != null) {
error(getMsg("error.module.options.without.info"));
return false;
}
-
if (vflag && fname == null) {
// Disable verbose output so that it does not appear
// on stdout along with file data
// error("Warning: -v option ignored");
vflag = false;
}
-
final String tmpbase = (fname == null)
? "tmpjar"
: fname.substring(fname.indexOf(File.separatorChar) + 1);
+
File tmpfile = createTemporaryFile(tmpbase, ".jar");
-
try (OutputStream out = new FileOutputStream(tmpfile)) {
- create(new BufferedOutputStream(out, 4096), manifest, moduleInfos);
+ create(new BufferedOutputStream(out, 4096), manifest);
}
-
if (nflag) {
File packFile = createTemporaryFile(tmpbase, ".pack");
try {
Packer packer = Pack200.newPacker();
Map<String, String> p = packer.properties();
p.put(Packer.EFFORT, "1"); // Minimal effort to conserve CPU
- try (
- JarFile jarFile = new JarFile(tmpfile.getCanonicalPath());
- OutputStream pack = new FileOutputStream(packFile)
- ) {
+ try (JarFile jarFile = new JarFile(tmpfile.getCanonicalPath());
+ OutputStream pack = new FileOutputStream(packFile))
+ {
packer.pack(jarFile, pack);
}
if (tmpfile.exists()) {
tmpfile.delete();
}
tmpfile = createTemporaryFile(tmpbase, ".jar");
- try (
- OutputStream out = new FileOutputStream(tmpfile);
- JarOutputStream jos = new JarOutputStream(out)
- ) {
+ try (OutputStream out = new FileOutputStream(tmpfile);
+ JarOutputStream jos = new JarOutputStream(out))
+ {
Unpacker unpacker = Pack200.newUnpacker();
unpacker.unpack(packFile, jos);
}
@@ -420,9 +332,7 @@
Files.deleteIfExists(packFile.toPath());
}
}
-
validateAndClose(tmpfile);
-
} else if (uflag) {
File inputFile = null, tmpFile = null;
if (fname != null) {
@@ -432,39 +342,20 @@
vflag = false;
tmpFile = createTemporaryFile("tmpjar", ".jar");
}
-
- Map<String,Path> moduleInfoPaths = new HashMap<>();
- for (int version : filesMap.keySet()) {
- String[] files = filesMap.get(version);
- expand(null, files, true, moduleInfoPaths, version);
+ expand();
+ try (FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
+ : new FileInputStream(FileDescriptor.in);
+ FileOutputStream out = new FileOutputStream(tmpFile);
+ InputStream manifest = (!Mflag && (mname != null)) ?
+ (new FileInputStream(mname)) : null;
+ ) {
+ boolean updateOk = update(in, new BufferedOutputStream(out),
+ manifest, moduleInfos, null);
+ if (ok) {
+ ok = updateOk;
+ }
}
-
- Map<String,byte[]> moduleInfos = new HashMap<>();
- for (Map.Entry<String,Path> e : moduleInfoPaths.entrySet())
- moduleInfos.put(e.getKey(), readModuleInfo(e.getValue()));
-
- try (
- FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
- : new FileInputStream(FileDescriptor.in);
- FileOutputStream out = new FileOutputStream(tmpFile);
- InputStream manifest = (!Mflag && (mname != null)) ?
- (new FileInputStream(mname)) : null;
- ) {
- boolean updateOk = update(in, new BufferedOutputStream(out),
- manifest, moduleInfos, null);
- if (ok) {
- ok = updateOk;
- }
- }
-
- // Consistency checks for modular jars.
- if (!moduleInfos.isEmpty()) {
- if(!checkServices(moduleInfos.get(MODULE_INFO)))
- return false;
- }
-
validateAndClose(tmpFile);
-
} else if (tflag) {
replaceFSC(filesMap);
// For the "list table contents" action, access using the
@@ -542,12 +433,15 @@
private void validateAndClose(File tmpfile) throws IOException {
if (ok && isMultiRelease) {
- ok = validate(tmpfile.getCanonicalPath());
- if (!ok) {
- error(formatMsg("error.validator.jarfile.invalid", fname));
+ try (JarFile jf = new JarFile(tmpfile)) {
+ ok = Validator.validate(this, jf);
+ if (!ok) {
+ error(formatMsg("error.validator.jarfile.invalid", fname));
+ }
+ } catch (IOException e) {
+ error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage()));
}
}
-
Path path = tmpfile.toPath();
try {
if (ok) {
@@ -572,78 +466,9 @@
Stream<String> filesToEntryNames(Map.Entry<Integer,String[]> fileEntries) {
int version = fileEntries.getKey();
+ Set<String> cpaths = pathsMap.get(version);
return Stream.of(fileEntries.getValue())
- .map(f -> (new EntryName(f, version)).entryName);
- }
-
- // sort base entries before versioned entries, and sort entry classes with
- // nested classes so that the top level class appears before the associated
- // nested class
- private Comparator<JarEntry> entryComparator = (je1, je2) -> {
- String s1 = je1.getName();
- String s2 = je2.getName();
- if (s1.equals(s2)) return 0;
- boolean b1 = s1.startsWith(VERSIONS_DIR);
- boolean b2 = s2.startsWith(VERSIONS_DIR);
- if (b1 && !b2) return 1;
- if (!b1 && b2) return -1;
- int n = 0; // starting char for String compare
- if (b1 && b2) {
- // normally strings would be sorted so "10" goes before "9", but
- // version number strings need to be sorted numerically
- n = VERSIONS_DIR.length(); // skip the common prefix
- int i1 = s1.indexOf('/', n);
- int i2 = s1.indexOf('/', n);
- if (i1 == -1) throw new InvalidJarException(s1);
- if (i2 == -1) throw new InvalidJarException(s2);
- // shorter version numbers go first
- if (i1 != i2) return i1 - i2;
- // otherwise, handle equal length numbers below
- }
- int l1 = s1.length();
- int l2 = s2.length();
- int lim = Math.min(l1, l2);
- for (int k = n; k < lim; k++) {
- char c1 = s1.charAt(k);
- char c2 = s2.charAt(k);
- if (c1 != c2) {
- // change natural ordering so '.' comes before '$'
- // i.e. top level classes come before nested classes
- if (c1 == '$' && c2 == '.') return 1;
- if (c1 == '.' && c2 == '$') return -1;
- return c1 - c2;
- }
- }
- return l1 - l2;
- };
-
- private boolean validate(String fname) {
- boolean valid;
-
- try (JarFile jf = new JarFile(fname)) {
- Validator validator = new Validator(this, jf);
- jf.stream()
- .filter(e -> !e.isDirectory())
- .filter(e -> !e.getName().equals(MANIFEST_NAME))
- .filter(e -> !e.getName().endsWith(MODULE_INFO))
- .sorted(entryComparator)
- .forEachOrdered(validator);
- valid = validator.isValid();
- } catch (IOException e) {
- error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage()));
- valid = false;
- } catch (InvalidJarException e) {
- error(formatMsg("error.validator.bad.entry.name", e.getMessage()));
- valid = false;
- }
- return valid;
- }
-
- private static class InvalidJarException extends RuntimeException {
- private static final long serialVersionUID = -3642329147299217726L;
- InvalidJarException(String msg) {
- super(msg);
- }
+ .map(f -> toVersionedName(toEntryName(f, cpaths, false), version));
}
/**
@@ -668,20 +493,22 @@
// Note: flags.length == 2 can be treated as the short version of
// the GNU option since the there cannot be any other options,
// excluding -C, as per the old way.
- if (flags.startsWith("--")
- || (flags.startsWith("-") && flags.length() == 2)) {
+ if (flags.startsWith("--") ||
+ (flags.startsWith("-") && flags.length() == 2)) {
try {
count = GNUStyleOptions.parseOptions(this, args);
} catch (GNUStyleOptions.BadArgs x) {
if (info == null) {
- error(x.getMessage());
- if (x.showUsage)
- Info.USAGE_TRYHELP.print(err);
+ if (x.showUsage) {
+ usageError(x.getMessage());
+ } else {
+ error(x.getMessage());
+ }
return false;
}
}
if (info != null) {
- info.print(out);
+ info.accept(out);
return true;
}
} else {
@@ -851,19 +678,55 @@
* Add the package of the given resource name if it's a .class
* or a resource in a named package.
*/
- boolean addPackageIfNamed(String name) {
+ void addPackageIfNamed(Set<String> packages, String name) {
if (name.startsWith(VERSIONS_DIR)) {
- throw new InternalError(name);
+ // trim the version dir prefix
+ int i0 = VERSIONS_DIR.length();
+ int i = name.indexOf('/', i0);
+ if (i <= 0) {
+ warn(formatMsg("warn.release.unexpected.versioned.entry", name));
+ return;
+ }
+ while (i0 < i) {
+ char c = name.charAt(i0);
+ if (c < '0' || c > '9') {
+ warn(formatMsg("warn.release.unexpected.versioned.entry", name));
+ return;
+ }
+ i0++;
+ }
+ name = name.substring(i + 1, name.length());
}
-
String pn = toPackageName(name);
// add if this is a class or resource in a package
if (Checks.isJavaIdentifier(pn)) {
packages.add(pn);
- return true;
+ }
+ }
+
+ private String toEntryName(String name, Set<String> cpaths, boolean isDir) {
+ name = name.replace(File.separatorChar, '/');
+ if (isDir) {
+ name = name.endsWith("/") ? name : name + "/";
}
+ String matchPath = "";
+ for (String path : cpaths) {
+ if (name.startsWith(path) && path.length() > matchPath.length()) {
+ matchPath = path;
+ }
+ }
+ name = safeName(name.substring(matchPath.length()));
+ // the old implementaton doesn't remove
+ // "./" if it was led by "/" (?)
+ if (name.startsWith("./")) {
+ name = name.substring(2);
+ }
+ return name;
+ }
- return false;
+ private static String toVersionedName(String name, int version) {
+ return version > BASE_VERSION
+ ? VERSIONS_DIR + version + "/" + name : name;
}
private static String toPackageName(String path) {
@@ -875,57 +738,23 @@
}
}
- /*
- * Returns true if the given entry is a valid entry of the given version.
- */
- private boolean isValidVersionedEntry(Entry entry, int version) {
- String name = entry.basename;
- if (name.startsWith(VERSIONS_DIR) && version != BASE_VERSION) {
- int i = name.indexOf('/', VERSIONS_DIR.length());
- // name == -1 -> not a versioned directory, something else
- if (i == -1)
- return false;
- try {
- String v = name.substring(VERSIONS_DIR.length(), i);
- return Integer.valueOf(v) == version;
- } catch (NumberFormatException x) {
- return false;
- }
+ private void expand() throws IOException {
+ for (int version : filesMap.keySet()) {
+ String[] files = filesMap.get(version);
+ expand(null, files, pathsMap.get(version), version);
}
- return true;
- }
-
- /*
- * Trim META-INF/versions/$version/ from the given name if the
- * given name is a versioned entry of the given version; or
- * of any version if the given version is BASE_VERSION
- */
- private String trimVersionsDir(String name, int version) {
- if (name.startsWith(VERSIONS_DIR)) {
- int i = name.indexOf('/', VERSIONS_DIR.length());
- if (i >= 0) {
- try {
- String v = name.substring(VERSIONS_DIR.length(), i);
- if (version == BASE_VERSION || Integer.valueOf(v) == version) {
- return name.substring(i + 1, name.length());
- }
- } catch (NumberFormatException x) {}
- }
- throw new InternalError("unexpected versioned entry: " +
- name + " version " + version);
- }
- return name;
}
/**
* Expands list of files to process into full list of all files that
* can be found by recursively descending directories.
+ *
+ * @param dir parent directory
+ * @param file s list of files to expand
+ * @param cpaths set of directories specified by -C option for the files
+ * @throws IOException if an I/O error occurs
*/
- void expand(File dir,
- String[] files,
- boolean isUpdate,
- Map<String,Path> moduleInfoPaths,
- int version)
+ private void expand(File dir, String[] files, Set<String> cpaths, int version)
throws IOException
{
if (files == null)
@@ -938,47 +767,48 @@
else
f = new File(dir, files[i]);
- Entry e = new Entry(version, f);
- String entryName = e.entryname;
- Entry entry = e;
- if (e.basename.startsWith(VERSIONS_DIR) && isValidVersionedEntry(e, version)) {
- entry = e.toVersionedEntry(version);
- }
- if (f.isFile()) {
- if (entryName.endsWith(MODULE_INFO)) {
- moduleInfoPaths.put(entryName, f.toPath());
- if (isUpdate)
- entryMap.put(entryName, entry);
- } else if (isValidVersionedEntry(entry, version)) {
- if (entries.add(entry)) {
- jarEntries.add(entryName);
- // add the package if it's a class or resource
- addPackageIfNamed(trimVersionsDir(entry.basename, version));
- if (isUpdate)
- entryMap.put(entryName, entry);
- }
- } else {
+ boolean isDir = f.isDirectory();
+ String name = toEntryName(f.getPath(), cpaths, isDir);
+
+ if (version != BASE_VERSION) {
+ if (name.startsWith(VERSIONS_DIR)) {
+ // the entry starts with VERSIONS_DIR and version != BASE_VERSION,
+ // which means the "[dirs|files]" in --release v [dirs|files]
+ // includes VERSIONS_DIR-ed entries --> warning and skip (?)
error(formatMsg2("error.release.unexpected.versioned.entry",
- entry.basename, String.valueOf(version)));
+ name, String.valueOf(version)));
ok = false;
+ return;
}
- } else if (f.isDirectory()) {
- if (isValidVersionedEntry(entry, version)) {
- if (entries.add(entry)) {
- if (isUpdate) {
- entryMap.put(entryName, entry);
- }
+ name = toVersionedName(name, version);
+ }
+
+ if (f.isFile()) {
+ Entry e = new Entry(f, name, false);
+ if (isModuleInfoEntry(name)) {
+ moduleInfos.putIfAbsent(name, Files.readAllBytes(f.toPath()));
+ if (uflag)
+ entryMap.put(name, e);
+ } else if (entries.add(e)) {
+ if (uflag)
+ entryMap.put(name, e);
+ }
+ } else if (isDir) {
+ Entry e = new Entry(f, name, true);
+ if (entries.add(e)) {
+ // utilize entryMap for the duplicate dir check even in
+ // case of cflag == true.
+ // dir name confilict/duplicate could happen with -C option.
+ // just remove the last "e" from the "entries" (zos will fail
+ // with "duplicated" entries), but continue expanding the
+ // sub tree
+ if (entryMap.containsKey(name)) {
+ entries.remove(e);
+ } else {
+ entryMap.put(name, e);
}
- } else if (entry.basename.equals(VERSIONS_DIR)) {
- if (vflag) {
- output(formatMsg("out.ignore.entry", entry.basename));
- }
- } else {
- error(formatMsg2("error.release.unexpected.versioned.entry",
- entry.basename, String.valueOf(version)));
- ok = false;
+ expand(f, f.list(), cpaths, version);
}
- expand(f, f.list(), isUpdate, moduleInfoPaths, version);
} else {
error(formatMsg("error.nosuch.fileordir", String.valueOf(f)));
ok = false;
@@ -989,52 +819,36 @@
/**
* Creates a new JAR file.
*/
- void create(OutputStream out, Manifest manifest, Map<String,byte[]> moduleInfos)
- throws IOException
+ void create(OutputStream out, Manifest manifest) throws IOException
{
- ZipOutputStream zos = new JarOutputStream(out);
- if (flag0) {
- zos.setMethod(ZipOutputStream.STORED);
- }
- // TODO: check module-info attributes against manifest ??
- if (manifest != null) {
- if (vflag) {
- output(getMsg("out.added.manifest"));
- }
- ZipEntry e = new ZipEntry(MANIFEST_DIR);
- e.setTime(System.currentTimeMillis());
- e.setSize(0);
- e.setCrc(0);
- zos.putNextEntry(e);
- e = new ZipEntry(MANIFEST_NAME);
- e.setTime(System.currentTimeMillis());
+ try (ZipOutputStream zos = new JarOutputStream(out)) {
if (flag0) {
- crc32Manifest(e, manifest);
+ zos.setMethod(ZipOutputStream.STORED);
}
- zos.putNextEntry(e);
- manifest.write(zos);
- zos.closeEntry();
- }
- for (Map.Entry<String,byte[]> mi : moduleInfos.entrySet()) {
- String entryName = mi.getKey();
- byte[] miBytes = mi.getValue();
- if (vflag) {
- output(formatMsg("out.added.module-info", entryName));
+ // TODO: check module-info attributes against manifest ??
+ if (manifest != null) {
+ if (vflag) {
+ output(getMsg("out.added.manifest"));
+ }
+ ZipEntry e = new ZipEntry(MANIFEST_DIR);
+ e.setTime(System.currentTimeMillis());
+ e.setSize(0);
+ e.setCrc(0);
+ zos.putNextEntry(e);
+ e = new ZipEntry(MANIFEST_NAME);
+ e.setTime(System.currentTimeMillis());
+ if (flag0) {
+ crc32Manifest(e, manifest);
+ }
+ zos.putNextEntry(e);
+ manifest.write(zos);
+ zos.closeEntry();
}
- ZipEntry e = new ZipEntry(mi.getKey());
- e.setTime(System.currentTimeMillis());
- if (flag0) {
- crc32ModuleInfo(e, miBytes);
+ updateModuleInfo(moduleInfos, zos);
+ for (Entry entry : entries) {
+ addFile(zos, entry);
}
- zos.putNextEntry(e);
- ByteArrayInputStream in = new ByteArrayInputStream(miBytes);
- in.transferTo(zos);
- zos.closeEntry();
}
- for (Entry entry : entries) {
- addFile(zos, entry);
- }
- zos.close();
}
private char toUpperCaseASCII(char c) {
@@ -1062,30 +876,6 @@
}
/**
- * Returns true of the given module-info's are located in acceptable
- * locations. Otherwise, outputs an appropriate message and returns false.
- */
- private boolean checkModuleInfos(Map<String,?> moduleInfos) {
- // there must always be, at least, a root module-info
- if (!moduleInfos.containsKey(MODULE_INFO)) {
- error(getMsg("error.versioned.info.without.root"));
- return false;
- }
-
- // module-info can only appear in the root, or a versioned section
- Optional<String> other = moduleInfos.keySet().stream()
- .filter(x -> !x.equals(MODULE_INFO))
- .filter(x -> !x.startsWith(VERSIONS_DIR))
- .findFirst();
-
- if (other.isPresent()) {
- error(formatMsg("error.unexpected.module-info", other.get()));
- return false;
- }
- return true;
- }
-
- /**
* Updates an existing jar file.
*/
boolean update(InputStream in, OutputStream out,
@@ -1099,6 +889,10 @@
boolean foundManifest = false;
boolean updateOk = true;
+ // All actual entries added/updated/existing, in the jar file (excl manifest
+ // and module-info.class ).
+ Set<String> jentries = new HashSet<>();
+
if (jarIndex != null) {
addIndex(jarIndex, zos);
}
@@ -1108,7 +902,7 @@
String name = e.getName();
boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME);
- boolean isModuleInfoEntry = name.endsWith(MODULE_INFO);
+ boolean isModuleInfoEntry = isModuleInfoEntry(name);
if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME))
|| (Mflag && isManifestEntry)) {
@@ -1127,7 +921,6 @@
return false;
}
}
-
// Update the manifest.
Manifest old = new Manifest(zis);
if (newManifest != null) {
@@ -1137,7 +930,7 @@
return false;
}
} else if (moduleInfos != null && isModuleInfoEntry) {
- moduleInfos.putIfAbsent(name, readModuleInfo(zis));
+ moduleInfos.putIfAbsent(name, zis.readAllBytes());
} else {
boolean isDir = e.isDirectory();
if (!entryMap.containsKey(name)) { // copy the old stuff
@@ -1160,11 +953,8 @@
entries.remove(ent);
isDir = ent.isDir;
}
-
- jarEntries.add(name);
if (!isDir) {
- // add the package if it's a class or resource
- addPackageIfNamed(trimVersionsDir(name, BASE_VERSION));
+ jentries.add(name);
}
}
}
@@ -1172,6 +962,9 @@
// add the remaining new files
for (Entry entry : entries) {
addFile(zos, entry);
+ if (!entry.isDir) {
+ jentries.add(entry.name);
+ }
}
if (!foundManifest) {
if (newManifest != null) {
@@ -1188,35 +981,24 @@
}
}
}
-
- if (moduleInfos != null && !moduleInfos.isEmpty()) {
- if (!checkModuleInfos(moduleInfos))
+ if (updateOk) {
+ if (moduleInfos != null && !moduleInfos.isEmpty()) {
+ Set<String> pkgs = new HashSet<>();
+ jentries.forEach( je -> addPackageIfNamed(pkgs, je));
+ addExtendedModuleAttributes(moduleInfos, pkgs);
+ updateOk = checkModuleInfo(moduleInfos.get(MODULE_INFO), jentries);
+ updateModuleInfo(moduleInfos, zos);
+ // TODO: check manifest main classes, etc
+ } else if (moduleVersion != null || modulesToHash != null) {
+ error(getMsg("error.module.options.without.info"));
updateOk = false;
-
- if (updateOk) {
- if (!addExtendedModuleAttributes(moduleInfos))
- updateOk = false;
}
-
- // TODO: check manifest main classes, etc
-
- if (updateOk) {
- for (Map.Entry<String,byte[]> mi : moduleInfos.entrySet()) {
- if (!updateModuleInfo(mi.getValue(), zos, mi.getKey()))
- updateOk = false;
- }
- }
- } else if (moduleVersion != null || modulesToHash != null) {
- error(getMsg("error.module.options.without.info"));
- updateOk = false;
}
-
zis.close();
zos.close();
return updateOk;
}
-
private void addIndex(JarIndex index, ZipOutputStream zos)
throws IOException
{
@@ -1232,20 +1014,25 @@
zos.closeEntry();
}
- private boolean updateModuleInfo(byte[] moduleInfoBytes, ZipOutputStream zos, String entryName)
+ private void updateModuleInfo(Map<String,byte[]> moduleInfos, ZipOutputStream zos)
throws IOException
{
- ZipEntry e = new ZipEntry(entryName);
- e.setTime(System.currentTimeMillis());
- if (flag0) {
- crc32ModuleInfo(e, moduleInfoBytes);
+ String fmt = uflag ? "out.update.module-info": "out.added.module-info";
+ for (Map.Entry<String,byte[]> mi : moduleInfos.entrySet()) {
+ String name = mi.getKey();
+ byte[] bytes = mi.getValue();
+ ZipEntry e = new ZipEntry(name);
+ e.setTime(System.currentTimeMillis());
+ if (flag0) {
+ crc32ModuleInfo(e, bytes);
+ }
+ zos.putNextEntry(e);
+ zos.write(bytes);
+ zos.closeEntry();
+ if (vflag) {
+ output(formatMsg(fmt, name));
+ }
}
- zos.putNextEntry(e);
- zos.write(moduleInfoBytes);
- if (vflag) {
- output(formatMsg("out.update.module-info", entryName));
- }
- return true;
}
private boolean updateManifest(Manifest m, ZipOutputStream zos)
@@ -1358,11 +1145,9 @@
* Adds a new file entry to the ZIP output stream.
*/
void addFile(ZipOutputStream zos, Entry entry) throws IOException {
- // skip the generation of directory entries for META-INF/versions/*/
- if (entry.basename.isEmpty()) return;
File file = entry.file;
- String name = entry.entryname;
+ String name = entry.name;
boolean isDir = entry.isDir;
if (name.equals("") || name.equals(".") || name.equals(zname)) {
@@ -1444,11 +1229,8 @@
* @throws IOException if an I/O error occurs
*/
private void copy(File from, OutputStream to) throws IOException {
- InputStream in = new FileInputStream(from);
- try {
+ try (InputStream in = new FileInputStream(from)) {
copy(in, to);
- } finally {
- in.close();
}
}
@@ -1461,11 +1243,8 @@
* @throws IOException if an I/O error occurs
*/
private void copy(InputStream from, File to) throws IOException {
- OutputStream out = new FileOutputStream(to);
- try {
+ try (OutputStream out = new FileOutputStream(to)) {
copy(from, out);
- } finally {
- out.close();
}
}
@@ -1825,7 +1604,7 @@
*/
void usageError(String s) {
err.println(s);
- Info.USAGE_TRYHELP.print(err);
+ err.println(getMsg("main.usage.summary.try"));
}
/**
@@ -1934,16 +1713,6 @@
return tmpfile;
}
- private static byte[] readModuleInfo(InputStream zis) throws IOException {
- return zis.readAllBytes();
- }
-
- private static byte[] readModuleInfo(Path path) throws IOException {
- try (InputStream is = Files.newInputStream(path)) {
- return is.readAllBytes();
- }
- }
-
// Modular jar support
static <T> String toString(Collection<T> c,
@@ -1951,7 +1720,6 @@
CharSequence suffix ) {
if (c.isEmpty())
return "";
-
return c.stream().map(e -> e.toString())
.collect(joining(", ", prefix, suffix));
}
@@ -2045,136 +1813,84 @@
md.osVersion().ifPresent(v -> sb.append("\n operating-system-version " + v));
- if (hashes != null) {
- hashes.names().stream().sorted().forEach(
- mod -> sb.append("\n hashes ").append(mod).append(" ")
- .append(hashes.algorithm()).append(" ")
- .append(toHex(hashes.hashFor(mod))));
+ if (hashes != null) {
+ hashes.names().stream().sorted().forEach(
+ mod -> sb.append("\n hashes ").append(mod).append(" ")
+ .append(hashes.algorithm()).append(" ")
+ .append(toHex(hashes.hashFor(mod))));
}
output(sb.toString());
}
private static String toHex(byte[] ba) {
- StringBuilder sb = new StringBuilder(ba.length);
+ StringBuilder sb = new StringBuilder(ba.length << 1);
for (byte b: ba) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
- private static String toBinaryName(String classname) {
+ static String toBinaryName(String classname) {
return (classname.replace('.', '/')) + ".class";
}
- /* A module must have the implementation class of the services it 'provides'. */
- private boolean checkServices(byte[] moduleInfoBytes)
+ private boolean checkModuleInfo(byte[] moduleInfoBytes, Set<String> entries)
throws IOException
{
- ModuleDescriptor md = ModuleDescriptor.read(ByteBuffer.wrap(moduleInfoBytes));
- Set<String> missing = md.provides()
- .stream()
- .map(Provides::providers)
- .flatMap(List::stream)
- .filter(p -> !jarEntries.contains(toBinaryName(p)))
- .collect(Collectors.toSet());
- if (missing.size() > 0) {
- missing.stream().forEach(s -> fatalError(formatMsg("error.missing.provider", s)));
- return false;
+ boolean ok = true;
+ if (moduleInfoBytes != null) { // no root module-info.class if null
+ try {
+ // ModuleDescriptor.read() checks open/exported pkgs vs packages
+ ModuleDescriptor md = ModuleDescriptor.read(ByteBuffer.wrap(moduleInfoBytes));
+ // A module must have the implementation class of the services it 'provides'.
+ if (md.provides().stream().map(Provides::providers).flatMap(List::stream)
+ .filter(p -> !entries.contains(toBinaryName(p)))
+ .peek(p -> fatalError(formatMsg("error.missing.provider", p)))
+ .count() != 0) {
+ ok = false;
+ }
+ } catch (InvalidModuleDescriptorException x) {
+ fatalError(x.getMessage());
+ ok = false;
+ }
}
- return true;
+ return ok;
}
/**
* Adds extended modules attributes to the given module-info's. The given
* Map values are updated in-place. Returns false if an error occurs.
*/
- private boolean addExtendedModuleAttributes(Map<String,byte[]> moduleInfos)
+ private void addExtendedModuleAttributes(Map<String,byte[]> moduleInfos,
+ Set<String> packages)
throws IOException
{
- assert !moduleInfos.isEmpty() && moduleInfos.get(MODULE_INFO) != null;
-
- ByteBuffer bb = ByteBuffer.wrap(moduleInfos.get(MODULE_INFO));
- ModuleDescriptor rd = ModuleDescriptor.read(bb);
-
- concealedPackages = findConcealedPackages(rd);
-
for (Map.Entry<String,byte[]> e: moduleInfos.entrySet()) {
- ModuleDescriptor vd = ModuleDescriptor.read(ByteBuffer.wrap(e.getValue()));
- if (!(isValidVersionedDescriptor(vd, rd)))
- return false;
- e.setValue(extendedInfoBytes(rd, vd, e.getValue(), packages));
+ ModuleDescriptor md = ModuleDescriptor.read(ByteBuffer.wrap(e.getValue()));
+ e.setValue(extendedInfoBytes(md, e.getValue(), packages));
}
- return true;
- }
-
- private Set<String> findConcealedPackages(ModuleDescriptor md) {
- Objects.requireNonNull(md);
- Set<String> concealed = new HashSet<>(packages);
- md.exports().stream().map(Exports::source).forEach(concealed::remove);
- md.opens().stream().map(Opens::source).forEach(concealed::remove);
- return concealed;
- }
-
- private static boolean isPlatformModule(String name) {
- return name.startsWith("java.") || name.startsWith("jdk.");
}
- /**
- * Tells whether or not the given versioned module descriptor's attributes
- * are valid when compared against the given root module descriptor.
- *
- * A versioned module descriptor must be identical to the root module
- * descriptor, with two exceptions:
- * - A versioned descriptor can have different non-public `requires`
- * clauses of platform ( `java.*` and `jdk.*` ) modules, and
- * - A versioned descriptor can have different `uses` clauses, even of
- * service types defined outside of the platform modules.
- */
- private boolean isValidVersionedDescriptor(ModuleDescriptor vd,
- ModuleDescriptor rd)
- throws IOException
- {
- if (!rd.name().equals(vd.name())) {
- fatalError(getMsg("error.versioned.info.name.notequal"));
- return false;
- }
- if (!rd.requires().equals(vd.requires())) {
- Set<Requires> rootRequires = rd.requires();
- for (Requires r : vd.requires()) {
- if (rootRequires.contains(r)) {
- continue;
- } else if (r.modifiers().contains(Requires.Modifier.TRANSITIVE)) {
- fatalError(getMsg("error.versioned.info.requires.transitive"));
+ static boolean isModuleInfoEntry(String name) {
+ // root or versioned module-info.class
+ if (name.endsWith(MODULE_INFO)) {
+ int end = name.length() - MODULE_INFO.length();
+ if (end == 0)
+ return true;
+ if (name.startsWith(VERSIONS_DIR)) {
+ int off = VERSIONS_DIR.length();
+ if (off == end) // meta-inf/versions/module-info.class
return false;
- } else if (!isPlatformModule(r.name())) {
- fatalError(getMsg("error.versioned.info.requires.added"));
- return false;
+ while (off < end - 1) {
+ char c = name.charAt(off++);
+ if (c < '0' || c > '9')
+ return false;
}
- }
- for (Requires r : rootRequires) {
- Set<Requires> mdRequires = vd.requires();
- if (mdRequires.contains(r)) {
- continue;
- } else if (!isPlatformModule(r.name())) {
- fatalError(getMsg("error.versioned.info.requires.dropped"));
- return false;
- }
+ return name.charAt(off) == '/';
}
}
- if (!rd.exports().equals(vd.exports())) {
- fatalError(getMsg("error.versioned.info.exports.notequal"));
- return false;
- }
- if (!rd.opens().equals(vd.opens())) {
- fatalError(getMsg("error.versioned.info.opens.notequal"));
- return false;
- }
- if (!rd.provides().equals(vd.provides())) {
- fatalError(getMsg("error.versioned.info.provides.notequal"));
- return false;
- }
- return true;
+ return false;
}
/**
@@ -2185,8 +1901,7 @@
* then the corresponding class file attributes are added to the
* module-info here.
*/
- private byte[] extendedInfoBytes(ModuleDescriptor rootDescriptor,
- ModuleDescriptor md,
+ private byte[] extendedInfoBytes(ModuleDescriptor md,
byte[] miBytes,
Set<String> packages)
throws IOException
@@ -2201,14 +1916,10 @@
// --main-class
if (ename != null)
extender.mainClass(ename);
- else if (rootDescriptor.mainClass().isPresent())
- extender.mainClass(rootDescriptor.mainClass().get());
// --module-version
if (moduleVersion != null)
extender.version(moduleVersion);
- else if (rootDescriptor.version().isPresent())
- extender.version(rootDescriptor.version().get());
// --hash-modules
if (modulesToHash != null) {
@@ -2218,8 +1929,7 @@
if (moduleHashes != null) {
extender.hashes(moduleHashes);
} else {
- // should it issue warning or silent?
- System.out.println("warning: no module is recorded in hash in " + mn);
+ warn("warning: no module is recorded in hash in " + mn);
}
}
@@ -2235,10 +1945,9 @@
* Compute and record hashes
*/
private class Hasher {
+ final ModuleHashesBuilder hashesBuilder;
final ModuleFinder finder;
- final Map<String, Path> moduleNameToPath;
final Set<String> modules;
- final Configuration configuration;
Hasher(ModuleDescriptor descriptor, String fname) throws IOException {
// Create a module finder that finds the modular JAR
// being created/updated
@@ -2268,119 +1977,46 @@
}
});
- // Determine the modules that matches the modulesToHash pattern
- this.modules = moduleFinder.findAll().stream()
- .map(moduleReference -> moduleReference.descriptor().name())
+ // Determine the modules that matches the pattern {@code modulesToHash}
+ Set<String> roots = finder.findAll().stream()
+ .map(ref -> ref.descriptor().name())
.filter(mn -> modulesToHash.matcher(mn).find())
.collect(Collectors.toSet());
- // a map from a module name to Path of the modular JAR
- this.moduleNameToPath = moduleFinder.findAll().stream()
- .map(ModuleReference::descriptor)
- .map(ModuleDescriptor::name)
- .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn)));
-
- Configuration config = null;
- try {
- config = Configuration.empty()
- .resolveRequires(ModuleFinder.ofSystem(), finder, modules);
- } catch (ResolutionException e) {
- // should it throw an error? or emit a warning
- System.out.println("warning: " + e.getMessage());
+ // use system module path unless it creates a modular JAR for
+ // a module that is present in the system image e.g. upgradeable
+ // module
+ ModuleFinder system;
+ String name = descriptor.name();
+ if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
+ system = ModuleFinder.of();
+ } else {
+ system = ModuleFinder.ofSystem();
}
- this.configuration = config;
- }
+ // get a resolved module graph
+ Configuration config =
+ Configuration.empty().resolveRequires(system, finder, roots);
- /**
- * Compute hashes of the modules that depend upon the specified
- * module directly or indirectly.
- */
- ModuleHashes computeHashes(String name) {
- // the transposed graph includes all modules in the resolved graph
- Map<String, Set<String>> graph = transpose();
+ // filter modules resolved from the system module finder
+ this.modules = config.modules().stream()
+ .map(ResolvedModule::name)
+ .filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
+ .collect(Collectors.toSet());
- // find the modules that transitively depend upon the specified name
- Deque<String> deque = new ArrayDeque<>();
- deque.add(name);
- Set<String> mods = visitNodes(graph, deque);
-
- // filter modules matching the pattern specified in --hash-modules,
- // as well as the modular jar file that is being created / updated
- Map<String, Path> modulesForHash = mods.stream()
- .filter(mn -> !mn.equals(name) && modules.contains(mn))
- .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get));
-
- if (modulesForHash.isEmpty())
- return null;
-
- return ModuleHashes.generate(modulesForHash, "SHA-256");
+ this.hashesBuilder = new ModuleHashesBuilder(config, modules);
}
/**
- * Returns all nodes traversed from the given roots.
+ * Compute hashes of the specified module.
+ *
+ * It records the hashing modules that depend upon the specified
+ * module directly or indirectly.
*/
- private Set<String> visitNodes(Map<String, Set<String>> graph,
- Deque<String> roots) {
- Set<String> visited = new HashSet<>();
- while (!roots.isEmpty()) {
- String mn = roots.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- // the given roots may not be part of the graph
- if (graph.containsKey(mn)) {
- for (String dm : graph.get(mn)) {
- if (!visited.contains(dm))
- roots.push(dm);
- }
- }
- }
- }
- return visited;
- }
-
- /**
- * Returns a transposed graph from the resolved module graph.
- */
- private Map<String, Set<String>> transpose() {
- Map<String, Set<String>> transposedGraph = new HashMap<>();
- Deque<String> deque = new ArrayDeque<>(modules);
+ ModuleHashes computeHashes(String name) {
+ if (hashesBuilder == null)
+ return null;
- Set<String> visited = new HashSet<>();
- while (!deque.isEmpty()) {
- String mn = deque.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- // add an empty set
- transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>());
-
- ResolvedModule resolvedModule = configuration.findModule(mn).get();
- for (ResolvedModule dm : resolvedModule.reads()) {
- String name = dm.name();
- if (!visited.contains(name)) {
- deque.push(name);
- }
- // reverse edge
- transposedGraph.computeIfAbsent(name, _k -> new HashSet<>())
- .add(mn);
- }
- }
- }
- return transposedGraph;
- }
-
- private Path moduleToPath(String name) {
- ModuleReference mref = moduleFinder.find(name).orElseThrow(
- () -> new InternalError(formatMsg2("error.hash.dep",name , name)));
-
- URI uri = mref.location().get();
- Path path = Paths.get(uri);
- String fn = path.getFileName().toString();
- if (!fn.endsWith(".jar")) {
- throw new UnsupportedOperationException(path + " is not a modular JAR");
- }
- return path;
+ return hashesBuilder.computeHashes(Set.of(name)).get(name);
}
}
}
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,32 +25,120 @@
package sun.tools.jar;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.module.InvalidModuleDescriptorException;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Exports;
+import java.lang.module.InvalidModuleDescriptorException;
+import java.lang.module.ModuleDescriptor.Opens;
+import java.lang.module.ModuleDescriptor.Provides;
+import java.lang.module.ModuleDescriptor.Requires;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
-final class Validator implements Consumer<JarEntry> {
+import static java.util.jar.JarFile.MANIFEST_NAME;
+import static sun.tools.jar.Main.VERSIONS_DIR;
+import static sun.tools.jar.Main.MODULE_INFO;
+import static sun.tools.jar.Main.getMsg;
+import static sun.tools.jar.Main.formatMsg;
+import static sun.tools.jar.Main.formatMsg2;
+import static sun.tools.jar.Main.toBinaryName;
+import static sun.tools.jar.Main.isModuleInfoEntry;
+
+final class Validator {
private final static boolean DEBUG = Boolean.getBoolean("jar.debug");
private final Map<String,FingerPrint> fps = new HashMap<>();
- private final int vdlen = Main.VERSIONS_DIR.length();
+ private static final int vdlen = VERSIONS_DIR.length();
private final Main main;
private final JarFile jf;
private int oldVersion = -1;
private String currentTopLevelName;
private boolean isValid = true;
+ private Set<String> concealedPkgs;
+ private ModuleDescriptor md;
- Validator(Main main, JarFile jf) {
+ private Validator(Main main, JarFile jf) {
this.main = main;
this.jf = jf;
+ loadModuleDescriptor();
+ }
+
+ static boolean validate(Main main, JarFile jf) throws IOException {
+ return new Validator(main, jf).validate();
+ }
+
+ private boolean validate() {
+ try {
+ jf.stream()
+ .filter(e -> !e.isDirectory() &&
+ !e.getName().equals(MANIFEST_NAME))
+ .sorted(entryComparator)
+ .forEachOrdered(e -> validate(e));
+ return isValid;
+ } catch (InvalidJarException e) {
+ error(formatMsg("error.validator.bad.entry.name", e.getMessage()));
+ }
+ return false;
+ }
+
+ private static class InvalidJarException extends RuntimeException {
+ private static final long serialVersionUID = -3642329147299217726L;
+ InvalidJarException(String msg) {
+ super(msg);
+ }
}
- boolean isValid() {
- return isValid;
- }
+ // sort base entries before versioned entries, and sort entry classes with
+ // nested classes so that the top level class appears before the associated
+ // nested class
+ private static Comparator<JarEntry> entryComparator = (je1, je2) -> {
+ String s1 = je1.getName();
+ String s2 = je2.getName();
+ if (s1.equals(s2)) return 0;
+ boolean b1 = s1.startsWith(VERSIONS_DIR);
+ boolean b2 = s2.startsWith(VERSIONS_DIR);
+ if (b1 && !b2) return 1;
+ if (!b1 && b2) return -1;
+ int n = 0; // starting char for String compare
+ if (b1 && b2) {
+ // normally strings would be sorted so "10" goes before "9", but
+ // version number strings need to be sorted numerically
+ n = VERSIONS_DIR.length(); // skip the common prefix
+ int i1 = s1.indexOf('/', n);
+ int i2 = s1.indexOf('/', n);
+ if (i1 == -1) throw new InvalidJarException(s1);
+ if (i2 == -1) throw new InvalidJarException(s2);
+ // shorter version numbers go first
+ if (i1 != i2) return i1 - i2;
+ // otherwise, handle equal length numbers below
+ }
+ int l1 = s1.length();
+ int l2 = s2.length();
+ int lim = Math.min(l1, l2);
+ for (int k = n; k < lim; k++) {
+ char c1 = s1.charAt(k);
+ char c2 = s2.charAt(k);
+ if (c1 != c2) {
+ // change natural ordering so '.' comes before '$'
+ // i.e. top level classes come before nested classes
+ if (c1 == '$' && c2 == '.') return 1;
+ if (c1 == '.' && c2 == '$') return -1;
+ return c1 - c2;
+ }
+ }
+ return l1 - l2;
+ };
/*
* Validator has state and assumes entries provided to accept are ordered
@@ -59,7 +147,7 @@
* classes must be ordered so that the top level class is before the associated
* nested class(es).
*/
- public void accept(JarEntry je) {
+ public void validate(JarEntry je) {
String entryName = je.getName();
// directories are always accepted
@@ -68,13 +156,20 @@
return;
}
+ // validate the versioned module-info
+ if (isModuleInfoEntry(entryName)) {
+ if (entryName.length() != MODULE_INFO.length())
+ checkModuleDescriptor(je);
+ return;
+ }
+
// figure out the version and basename from the JarEntry
int version;
String basename;
- if (entryName.startsWith(Main.VERSIONS_DIR)) {
+ if (entryName.startsWith(VERSIONS_DIR)) {
int n = entryName.indexOf("/", vdlen);
if (n == -1) {
- main.error(Main.formatMsg("error.validator.version.notnumber", entryName));
+ error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
@@ -82,12 +177,12 @@
try {
version = Integer.parseInt(v);
} catch (NumberFormatException x) {
- main.error(Main.formatMsg("error.validator.version.notnumber", entryName));
+ error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
if (n == entryName.length()) {
- main.error(Main.formatMsg("error.validator.entryname.tooshort", entryName));
+ error(formatMsg("error.validator.entryname.tooshort", entryName));
isValid = false;
return;
}
@@ -108,7 +203,7 @@
try (InputStream is = jf.getInputStream(je)) {
fp = new FingerPrint(basename, is.readAllBytes());
} catch (IOException x) {
- main.error(x.getMessage());
+ error(x.getMessage());
isValid = false;
return;
}
@@ -123,7 +218,7 @@
fps.put(internalName, fp);
return;
}
- main.error(Main.formatMsg("error.validator.isolated.nested.class", entryName));
+ error(formatMsg("error.validator.isolated.nested.class", entryName));
isValid = false;
return;
}
@@ -153,11 +248,11 @@
}
if (fp.isPublicClass()) {
if (!isConcealed(internalName)) {
- main.error(Main.formatMsg("error.validator.new.public.class", entryName));
+ error(Main.formatMsg("error.validator.new.public.class", entryName));
isValid = false;
return;
}
- main.warn(Main.formatMsg("warn.validator.concealed.public.class", entryName));
+ warn(formatMsg("warn.validator.concealed.public.class", entryName));
debug("%s is a public class entry in a concealed package", entryName);
}
debug("%s is a non-public class entry", entryName);
@@ -173,7 +268,7 @@
// are the two classes/resources identical?
if (fp.isIdentical(matchFp)) {
- main.warn(Main.formatMsg("warn.validator.identical.entry", entryName));
+ warn(formatMsg("warn.validator.identical.entry", entryName));
return; // it's okay, just takes up room
}
debug("sha1 not equal -- different bytes");
@@ -188,12 +283,12 @@
}
debug("%s is a class entry", entryName);
if (!fp.isCompatibleVersion(matchFp)) {
- main.error(Main.formatMsg("error.validator.incompatible.class.version", entryName));
+ error(formatMsg("error.validator.incompatible.class.version", entryName));
isValid = false;
return;
}
if (!fp.isSameAPI(matchFp)) {
- main.error(Main.formatMsg("error.validator.different.api", entryName));
+ error(formatMsg("error.validator.different.api", entryName));
isValid = false;
return;
}
@@ -208,17 +303,118 @@
}
debug("%s is a resource", entryName);
- main.warn(Main.formatMsg("warn.validator.resources.with.same.name", entryName));
+ warn(formatMsg("warn.validator.resources.with.same.name", entryName));
fps.put(internalName, fp);
return;
}
+ private void loadModuleDescriptor() {
+ ZipEntry je = jf.getEntry(MODULE_INFO);
+ if (je != null) {
+ try (InputStream jis = jf.getInputStream(je)) {
+ md = ModuleDescriptor.read(jis);
+ concealedPkgs = new HashSet<>(md.packages());
+ md.exports().stream().map(Exports::source).forEach(concealedPkgs::remove);
+ md.opens().stream().map(Opens::source).forEach(concealedPkgs::remove);
+ return;
+ } catch (Exception x) {
+ error(x.getMessage() + " : " + je.getName());
+ this.isValid = false;
+ }
+ }
+ md = null;
+ concealedPkgs = Collections.emptySet();
+ }
+
+ private static boolean isPlatformModule(String name) {
+ return name.startsWith("java.") || name.startsWith("jdk.");
+ }
+
+ /**
+ * Checks whether or not the given versioned module descriptor's attributes
+ * are valid when compared against the root module descriptor.
+ *
+ * A versioned module descriptor must be identical to the root module
+ * descriptor, with two exceptions:
+ * - A versioned descriptor can have different non-public `requires`
+ * clauses of platform ( `java.*` and `jdk.*` ) modules, and
+ * - A versioned descriptor can have different `uses` clauses, even of
+ * service types defined outside of the platform modules.
+ */
+ private void checkModuleDescriptor(JarEntry je) {
+ try (InputStream is = jf.getInputStream(je)) {
+ ModuleDescriptor root = this.md;
+ ModuleDescriptor md = null;
+ try {
+ md = ModuleDescriptor.read(is);
+ } catch (InvalidModuleDescriptorException x) {
+ error(x.getMessage());
+ isValid = false;
+ return;
+ }
+ if (root == null) {
+ this.md = md;
+ } else {
+ if (!root.name().equals(md.name())) {
+ error(getMsg("error.versioned.info.name.notequal"));
+ isValid = false;
+ }
+ if (!root.requires().equals(md.requires())) {
+ Set<Requires> rootRequires = root.requires();
+ for (Requires r : md.requires()) {
+ if (rootRequires.contains(r))
+ continue;
+ if (r.modifiers().contains(Requires.Modifier.TRANSITIVE)) {
+ error(getMsg("error.versioned.info.requires.transitive"));
+ isValid = false;
+ } else if (!isPlatformModule(r.name())) {
+ error(getMsg("error.versioned.info.requires.added"));
+ isValid = false;
+ }
+ }
+ for (Requires r : rootRequires) {
+ Set<Requires> mdRequires = md.requires();
+ if (mdRequires.contains(r))
+ continue;
+ if (!isPlatformModule(r.name())) {
+ error(getMsg("error.versioned.info.requires.dropped"));
+ isValid = false;
+ }
+ }
+ }
+ if (!root.exports().equals(md.exports())) {
+ error(getMsg("error.versioned.info.exports.notequal"));
+ isValid = false;
+ }
+ if (!root.opens().equals(md.opens())) {
+ error(getMsg("error.versioned.info.opens.notequal"));
+ isValid = false;
+ }
+ if (!root.provides().equals(md.provides())) {
+ error(getMsg("error.versioned.info.provides.notequal"));
+ isValid = false;
+ }
+ if (!root.mainClass().equals(md.mainClass())) {
+ error(formatMsg("error.validator.info.manclass.notequal", je.getName()));
+ isValid = false;
+ }
+ if (!root.version().equals(md.version())) {
+ error(formatMsg("error.validator.info.version.notequal", je.getName()));
+ isValid = false;
+ }
+ }
+ } catch (IOException x) {
+ error(x.getMessage());
+ isValid = false;
+ }
+ }
+
private boolean checkInternalName(String entryName, String basename, String internalName) {
String className = className(basename);
if (internalName.equals(className)) {
return true;
}
- main.error(Main.formatMsg2("error.validator.names.mismatch",
+ error(formatMsg2("error.validator.names.mismatch",
entryName, internalName.replace("/", ".")));
return false;
}
@@ -231,7 +427,7 @@
return true;
}
debug("top level class was not accepted");
- main.error(Main.formatMsg("error.validator.isolated.nested.class", entryName));
+ error(formatMsg("error.validator.isolated.nested.class", entryName));
return false;
}
@@ -240,16 +436,24 @@
}
private boolean isConcealed(String internalName) {
- if (main.concealedPackages.isEmpty()) {
+ if (concealedPkgs.isEmpty()) {
return false;
}
int idx = internalName.lastIndexOf('/');
String pkgName = idx != -1 ? internalName.substring(0, idx).replace('/', '.') : "";
- return main.concealedPackages.contains(pkgName);
+ return concealedPkgs.contains(pkgName);
}
private void debug(String fmt, Object... args) {
if (DEBUG) System.err.format(fmt, args);
}
+
+ private void error(String msg) {
+ main.error(msg);
+ }
+
+ private void warn(String msg) {
+ main.warn(msg);
+ }
+
}
-
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Tue Jan 24 00:30:23 2017 +0100
@@ -66,23 +66,6 @@
Unexpected module descriptor {0}
error.module.descriptor.not.found=\
Module descriptor not found
-error.versioned.info.without.root=\
- module-info.class found in a versioned directory without module-info.class \
- in the root
-error.versioned.info.name.notequal=\
- module-info.class in a versioned directory contains incorrect name
-error.versioned.info.requires.transitive=\
- module-info.class in a versioned directory contains additional "requires transitive"
-error.versioned.info.requires.added=\
- module-info.class in a versioned directory contains additional "requires"
-error.versioned.info.requires.dropped=\
- module-info.class in a versioned directory contains missing "requires"
-error.versioned.info.exports.notequal=\
- module-info.class in a versioned directory contains different "exports"
-error.versioned.info.opens.notequal=\
- module-info.class in a versioned directory contains different "opens"
-error.versioned.info.provides.notequal=\
- module-info.class in a versioned directory contains different "provides"
error.invalid.versioned.module.attribute=\
Invalid module descriptor attribute {0}
error.missing.provider=\
@@ -113,6 +96,24 @@
entry: {0}, contains a class with different api from earlier version
error.validator.names.mismatch=\
entry: {0}, contains a class with internal name {1}, names do not match
+error.validator.info.name.notequal=\
+ module-info.class in a versioned directory contains incorrect name
+error.validator.info.requires.transitive=\
+ module-info.class in a versioned directory contains additional "requires transitive"
+error.validator.info.requires.added=\
+ module-info.class in a versioned directory contains additional "requires"
+error.validator.info.requires.dropped=\
+ module-info.class in a versioned directory contains missing "requires"
+error.validator.info.exports.notequal=\
+ module-info.class in a versioned directory contains different "exports"
+error.validator.info.opens.notequal=\
+ module-info.class in a versioned directory contains different "opens"
+error.validator.info.provides.notequal=\
+ module-info.class in a versioned directory contains different "provides"
+error.validator.info.version.notequal=\
+ {0}: module-info.class in a versioned directory contains different "version"
+error.validator.info.manclass.notequal=\
+ {0}: module-info.class in a versioned directory contains different "main-class"
warn.validator.identical.entry=\
Warning: entry {0} contains a class that\n\
is identical to an entry already in the jar
@@ -122,6 +123,8 @@
Warning: entry {0} is a public class\n\
in a concealed package, placing this jar on the class path will result\n\
in incompatible public interfaces
+warn.release.unexpected.versioned.entry=\
+ unexpected versioned entry {0}
out.added.manifest=\
added manifest
out.added.module-info=\
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=--module-version oder --hash-modules ohne module-info.class
error.unexpected.module-info=Unerwarteter Moduldeskriptor {0}
error.module.descriptor.not.found=Moduldeskriptor nicht gefunden
-error.versioned.info.without.root=module-info.class in einem versionierten Verzeichnis gefunden, in der Root ist module-info.class jedoch nicht vorhanden
-error.versioned.info.name.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt falschen Namen
-error.versioned.info.requires.public=module-info.class in einem versionierten Verzeichnis enth\u00E4lt zus\u00E4tzlichen "requires public"
-error.versioned.info.requires.added=module-info.class in einem versionierten Verzeichnis enth\u00E4lt zus\u00E4tzlichen "requires"
-error.versioned.info.requires.dropped=module-info.class in einem versionierten Verzeichnis enth\u00E4lt fehlenden "requires"
-error.versioned.info.exports.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt unterschiedliche "exports"
-error.versioned.info.provides.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt unterschiedliche "provides"
+error.validator.info.without.root=module-info.class in einem versionierten Verzeichnis gefunden, in der Root ist module-info.class jedoch nicht vorhanden
+error.validator.info.name.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt falschen Namen
+error.validator.info.requires.public=module-info.class in einem versionierten Verzeichnis enth\u00E4lt zus\u00E4tzlichen "requires public"
+error.validator.info.requires.added=module-info.class in einem versionierten Verzeichnis enth\u00E4lt zus\u00E4tzlichen "requires"
+error.validator.info.requires.dropped=module-info.class in einem versionierten Verzeichnis enth\u00E4lt fehlenden "requires"
+error.validator.info.exports.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt unterschiedliche "exports"
+error.validator.info.provides.notequal=module-info.class in einem versionierten Verzeichnis enth\u00E4lt unterschiedliche "provides"
error.invalid.versioned.module.attribute=Ung\u00FCltiges Moduldeskriptorattribut {0}
error.missing.provider=Serviceprovider nicht gefunden: {0}
error.release.value.notnumber=Release {0} nicht g\u00FCltig
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_es.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_es.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=Uno de --module-version o -hash-modules sin module-info.class
error.unexpected.module-info=Descriptor de m\u00F3dulo inesperado {0}
error.module.descriptor.not.found=No se ha encontrado el descriptor de m\u00F3dulo
-error.versioned.info.without.root=Se ha encontrado module-info.class en un directorio con versi\u00F3n sin module-info.class en la ra\u00EDz
-error.versioned.info.name.notequal=module-info.class en un directorio con versi\u00F3n contiene un nombre incorrecto
-error.versioned.info.requires.public=module-info.class en un directorio con versiones contiene "requires public" adicionales
-error.versioned.info.requires.added=module-info.class en un directorio con versi\u00F3n contiene "requires" adicionales
-error.versioned.info.requires.dropped=module-info.class en un directorio con versiones contiene "requires" que faltan
-error.versioned.info.exports.notequal=module-info.class en un directorio con versiones contiene "exports" diferentes
-error.versioned.info.provides.notequal=module-info.class en un directorio con versiones contiene "provides" diferentes
+error.validator.info.without.root=Se ha encontrado module-info.class en un directorio con versi\u00F3n sin module-info.class en la ra\u00EDz
+error.validator.info.name.notequal=module-info.class en un directorio con versi\u00F3n contiene un nombre incorrecto
+error.validator.info.requires.public=module-info.class en un directorio con versiones contiene "requires public" adicionales
+error.validator.info.requires.added=module-info.class en un directorio con versi\u00F3n contiene "requires" adicionales
+error.validator.info.requires.dropped=module-info.class en un directorio con versiones contiene "requires" que faltan
+error.validator.info.exports.notequal=module-info.class en un directorio con versiones contiene "exports" diferentes
+error.validator.info.provides.notequal=module-info.class en un directorio con versiones contiene "provides" diferentes
error.invalid.versioned.module.attribute=Atributo de descriptor de m\u00F3dulo no v\u00E1lido {0}
error.missing.provider=No se ha encontrado el proveedor de servicios: {0}
error.release.value.notnumber=versi\u00F3n {0} no v\u00E1lida
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_fr.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_fr.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=Une des options --module-version ou --hash-modules sans module-info.class
error.unexpected.module-info=Descripteur de module {0} inattendu
error.module.descriptor.not.found=Descripteur de module introuvable
-error.versioned.info.without.root=module-info.class a \u00E9t\u00E9 d\u00E9tect\u00E9 dans un r\u00E9pertoire avec num\u00E9ro de version sans module-info.class dans la racine
-error.versioned.info.name.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient un nom incorrect
-error.versioned.info.requires.public=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires public" suppl\u00E9mentaires
-error.versioned.info.requires.added=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" suppl\u00E9mentaires
-error.versioned.info.requires.dropped=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" manquants
-error.versioned.info.exports.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "exports" diff\u00E9rents
-error.versioned.info.provides.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "provides" diff\u00E9rents
+error.validator.info.without.root=module-info.class a \u00E9t\u00E9 d\u00E9tect\u00E9 dans un r\u00E9pertoire avec num\u00E9ro de version sans module-info.class dans la racine
+error.validator.info.name.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient un nom incorrect
+error.validator.info.requires.public=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires public" suppl\u00E9mentaires
+error.validator.info.requires.added=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" suppl\u00E9mentaires
+error.validator.info.requires.dropped=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "requires" manquants
+error.validator.info.exports.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "exports" diff\u00E9rents
+error.validator.info.provides.notequal=module-info.class dans un r\u00E9pertoire avec num\u00E9ro de version contient des mots-cl\u00E9s "provides" diff\u00E9rents
error.invalid.versioned.module.attribute=Attribut de descripteur de module non valide {0}
error.missing.provider=Fournisseur de services introuvable : {0}
error.release.value.notnumber=version {0} non valide
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_it.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_it.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=Una delle opzioni --module-version o --hash-modules non contiene module-info.class
error.unexpected.module-info=Descrittore di modulo {0} imprevisto
error.module.descriptor.not.found=Descrittore di modulo non trovato
-error.versioned.info.without.root=module-info.class trovato in una directory con controllo delle versioni senza module-info.class nella radice
-error.versioned.info.name.notequal=module-info.class in una directory con controllo delle versioni contiene un nome errato
-error.versioned.info.requires.public=module-info.class in una directory con controllo delle versioni contiene valori "requires public" aggiuntivi
-error.versioned.info.requires.added=module-info.class in una directory con controllo delle versioni contiene valori "requires" aggiuntivi
-error.versioned.info.requires.dropped=module-info.class in una directory con controllo delle versioni contiene valori "requires" mancanti
-error.versioned.info.exports.notequal=module-info.class in una directory con controllo delle versioni contiene "exports" differenti
-error.versioned.info.provides.notequal=module-info.class in una directory con controllo delle versioni contiene valori "provides" differenti
+error.validator.info.without.root=module-info.class trovato in una directory con controllo delle versioni senza module-info.class nella radice
+error.validator.info.name.notequal=module-info.class in una directory con controllo delle versioni contiene un nome errato
+error.validator.info.requires.public=module-info.class in una directory con controllo delle versioni contiene valori "requires public" aggiuntivi
+error.validator.info.requires.added=module-info.class in una directory con controllo delle versioni contiene valori "requires" aggiuntivi
+error.validator.info.requires.dropped=module-info.class in una directory con controllo delle versioni contiene valori "requires" mancanti
+error.validator.info.exports.notequal=module-info.class in una directory con controllo delle versioni contiene "exports" differenti
+error.validator.info.provides.notequal=module-info.class in una directory con controllo delle versioni contiene valori "provides" differenti
error.invalid.versioned.module.attribute=Attributo descrittore del modulo {0} non valido.
error.missing.provider=Provider di servizi non trovato: {0}
error.release.value.notnumber=release {0} non valida
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=--module-version\u307E\u305F\u306F--hash-modules\u306E\u3044\u305A\u308C\u304B\u3067module-info.class\u304C\u3042\u308A\u307E\u305B\u3093
error.unexpected.module-info=\u4E88\u671F\u3057\u306A\u3044\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF{0}
error.module.descriptor.not.found=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-error.versioned.info.without.root=module-info.class\u304C\u3001\u30EB\u30FC\u30C8\u306Bmodule-info.class\u306E\u306A\u3044\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u898B\u3064\u304B\u308A\u307E\u3057\u305F
-error.versioned.info.name.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B63\u3057\u304F\u306A\u3044\u540D\u524D\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.public=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires public"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.added=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.requires.dropped=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B20\u843D\u3057\u3066\u3044\u308B"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.exports.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"exports"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
-error.versioned.info.provides.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"provides"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.without.root=module-info.class\u304C\u3001\u30EB\u30FC\u30C8\u306Bmodule-info.class\u306E\u306A\u3044\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u898B\u3064\u304B\u308A\u307E\u3057\u305F
+error.validator.info.name.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B63\u3057\u304F\u306A\u3044\u540D\u524D\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.requires.public=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires public"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.requires.added=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u8FFD\u52A0\u306E"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.requires.dropped=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u6B20\u843D\u3057\u3066\u3044\u308B"requires"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.exports.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"exports"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
+error.validator.info.provides.notequal=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u3055\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306Emodule-info.class\u306B\u7570\u306A\u308B"provides"\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059
error.invalid.versioned.module.attribute=\u30E2\u30B8\u30E5\u30FC\u30EB\u30FB\u30C7\u30A3\u30B9\u30AF\u30EA\u30D7\u30BF\u5C5E\u6027{0}\u304C\u7121\u52B9\u3067\u3059
error.missing.provider=\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}
error.release.value.notnumber=\u30EA\u30EA\u30FC\u30B9{0}\u306F\u6709\u52B9\u3067\u306F\u3042\u308A\u307E\u305B\u3093
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ko.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ko.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=module-info.class \uC5C6\uC774 --module-version \uB610\uB294 --hash-modules \uC911 \uD558\uB098
error.unexpected.module-info=\uC608\uC0C1\uCE58 \uC54A\uC740 \uBAA8\uB4C8 \uAE30\uC220\uC790 {0}
error.module.descriptor.not.found=\uBAA8\uB4C8 \uAE30\uC220\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC74C
-error.versioned.info.without.root=\uB8E8\uD2B8\uC5D0\uC11C module-info.class \uC5C6\uC774 \uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C module-info.class\uAC00 \uBC1C\uACAC\uB428
-error.versioned.info.name.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uC798\uBABB\uB41C \uC774\uB984\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.public=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires public" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.added=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.requires.dropped=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB204\uB77D\uB41C "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.exports.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "exports" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
-error.versioned.info.provides.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "provides" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.validator.info.without.root=\uB8E8\uD2B8\uC5D0\uC11C module-info.class \uC5C6\uC774 \uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C module-info.class\uAC00 \uBC1C\uACAC\uB428
+error.validator.info.name.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uC798\uBABB\uB41C \uC774\uB984\uC774 \uD3EC\uD568\uB428
+error.validator.info.requires.public=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires public" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.validator.info.requires.added=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uCD94\uAC00 "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.validator.info.requires.dropped=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB204\uB77D\uB41C "requires" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.validator.info.exports.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "exports" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
+error.validator.info.provides.notequal=\uBC84\uC804 \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uC758 module-info.class\uC5D0 \uB2E4\uB978 "provides" \uD56D\uBAA9\uC774 \uD3EC\uD568\uB428
error.invalid.versioned.module.attribute=\uBD80\uC801\uD569\uD55C \uBAA8\uB4C8 \uAE30\uC220\uC790 \uC18D\uC131 {0}
error.missing.provider=\uC11C\uBE44\uC2A4 \uC81C\uACF5\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC74C: {0}
error.release.value.notnumber=\uB9B4\uB9AC\uC2A4 {0}\uC774(\uAC00) \uBD80\uC801\uD569\uD568
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_pt_BR.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_pt_BR.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=Um dentre --module-version ou --hash-modules est\u00E1 sem module-info.class
error.unexpected.module-info=Descritor de m\u00F3dulo inesperado {0}
error.module.descriptor.not.found=Descritor de m\u00F3dulo n\u00E3o encontrado
-error.versioned.info.without.root=module-info.class encontrado em um diret\u00F3rio com controle de vers\u00E3o sem module-info.class na raiz
-error.versioned.info.name.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m nome incorreto
-error.versioned.info.requires.public=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires public" adicional
-error.versioned.info.requires.added=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires" adicional
-error.versioned.info.requires.dropped=module-info.class em um diret\u00F3rio com controle de vers\u00E3o falta "requires"
-error.versioned.info.exports.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "exports" diferente
-error.versioned.info.provides.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "provides" diferente
+error.validator.info.without.root=module-info.class encontrado em um diret\u00F3rio com controle de vers\u00E3o sem module-info.class na raiz
+error.validator.info.name.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m nome incorreto
+error.validator.info.requires.public=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires public" adicional
+error.validator.info.requires.added=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "requires" adicional
+error.validator.info.requires.dropped=module-info.class em um diret\u00F3rio com controle de vers\u00E3o falta "requires"
+error.validator.info.exports.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "exports" diferente
+error.validator.info.provides.notequal=module-info.class em um diret\u00F3rio com controle de vers\u00E3o cont\u00E9m "provides" diferente
error.invalid.versioned.module.attribute=Atributo {0} de descritor de m\u00F3dulo inv\u00E1lido
error.missing.provider=Prestador de servi\u00E7os n\u00E3o encontrado: {0}
error.release.value.notnumber=release {0} n\u00E3o v\u00E1lida
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_sv.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_sv.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=--module-version eller --hash-modules utan module-info.class
error.unexpected.module-info=Ov\u00E4ntad moduldeskriptor, {0}
error.module.descriptor.not.found=Moduldeskriptorn hittades inte
-error.versioned.info.without.root=module-info.class hittades i en versionshanterad katalog utan module-info.class i roten
-error.versioned.info.name.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller ett felaktigt namn
-error.versioned.info.requires.public=module-info.class i en versionshanterad katalog inneh\u00E5ller fler "requires public"
-error.versioned.info.requires.added=module-info.class i en versionshanterad katalog inneh\u00E5ller fler "requires"
-error.versioned.info.requires.dropped=module-info.class i en versionshanterad katalog inneh\u00E5ller saknade "requires"
-error.versioned.info.exports.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller olika "exports"
-error.versioned.info.provides.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller olika "provides"
+error.validator.info.without.root=module-info.class hittades i en versionshanterad katalog utan module-info.class i roten
+error.validator.info.name.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller ett felaktigt namn
+error.validator.info.requires.public=module-info.class i en versionshanterad katalog inneh\u00E5ller fler "requires public"
+error.validator.info.requires.added=module-info.class i en versionshanterad katalog inneh\u00E5ller fler "requires"
+error.validator.info.requires.dropped=module-info.class i en versionshanterad katalog inneh\u00E5ller saknade "requires"
+error.validator.info.exports.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller olika "exports"
+error.validator.info.provides.notequal=module-info.class i en versionshanterad katalog inneh\u00E5ller olika "provides"
error.invalid.versioned.module.attribute=Ogiltigt attribut f\u00F6r moduldeskriptor, {0}
error.missing.provider=Tj\u00E4nsteleverant\u00F6ren hittades inte: {0}
error.release.value.notnumber=utg\u00E5va {0} \u00E4r inte giltig
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=--module-version \u6216 --hash-modules \u4E4B\u4E00\u6CA1\u6709 module-info.class
error.unexpected.module-info=\u610F\u5916\u7684\u6A21\u5757\u63CF\u8FF0\u7B26 {0}
error.module.descriptor.not.found=\u627E\u4E0D\u5230\u6A21\u5757\u63CF\u8FF0\u7B26
-error.versioned.info.without.root=\u5728\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u627E\u5230\u4E86 module-info.class, \u4F46\u6839\u4E2D\u6CA1\u6709 module-info.class
-error.versioned.info.name.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u786E\u7684\u540D\u79F0
-error.versioned.info.requires.public=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires public"
-error.versioned.info.requires.added=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires"
-error.versioned.info.requires.dropped=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u7F3A\u5C11\u7684 "requires"
-error.versioned.info.exports.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
-error.versioned.info.provides.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
+error.validator.info.without.root=\u5728\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u627E\u5230\u4E86 module-info.class, \u4F46\u6839\u4E2D\u6CA1\u6709 module-info.class
+error.validator.info.name.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u786E\u7684\u540D\u79F0
+error.validator.info.requires.public=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires public"
+error.validator.info.requires.added=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u989D\u5916\u7684 "requires"
+error.validator.info.requires.dropped=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u7F3A\u5C11\u7684 "requires"
+error.validator.info.exports.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
+error.validator.info.provides.notequal=\u7248\u672C\u5316\u76EE\u5F55\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
error.invalid.versioned.module.attribute=\u65E0\u6548\u7684\u6A21\u5757\u63CF\u8FF0\u7B26\u5C5E\u6027 {0}
error.missing.provider=\u672A\u627E\u5230\u670D\u52A1\u63D0\u4F9B\u65B9: {0}
error.release.value.notnumber=\u53D1\u884C\u7248 {0} \u65E0\u6548
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_TW.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_TW.properties Tue Jan 24 00:30:23 2017 +0100
@@ -42,13 +42,13 @@
error.module.options.without.info=--module-version \u6216 --hash-modules \u5176\u4E2D\u4E00\u500B\u6C92\u6709 module-info.class
error.unexpected.module-info=\u672A\u9810\u671F\u7684\u6A21\u7D44\u63CF\u8FF0\u5340 {0}
error.module.descriptor.not.found=\u627E\u4E0D\u5230\u6A21\u7D44\u63CF\u8FF0\u5340
-error.versioned.info.without.root=\u5728\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u767C\u73FE module-info.class\uFF0C\u4F46\u662F\u6839\u4E2D\u6C92\u6709 module-info.class
-error.versioned.info.name.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u78BA\u7684\u540D\u7A31
-error.versioned.info.requires.public=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires public"
-error.versioned.info.requires.added=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires"
-error.versioned.info.requires.dropped=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u907A\u6F0F\u7684 "requires"
-error.versioned.info.exports.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
-error.versioned.info.provides.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
+error.validator.info.without.root=\u5728\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u767C\u73FE module-info.class\uFF0C\u4F46\u662F\u6839\u4E2D\u6C92\u6709 module-info.class
+error.validator.info.name.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u6B63\u78BA\u7684\u540D\u7A31
+error.validator.info.requires.public=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires public"
+error.validator.info.requires.added=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u984D\u5916\u7684 "requires"
+error.validator.info.requires.dropped=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u907A\u6F0F\u7684 "requires"
+error.validator.info.exports.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "exports"
+error.validator.info.provides.notequal=\u5DF2\u555F\u52D5\u591A\u7248\u672C\u529F\u80FD\u76EE\u9304\u4E2D\u7684 module-info.class \u5305\u542B\u4E0D\u540C\u7684 "provides"
error.invalid.versioned.module.attribute=\u6A21\u7D44\u63CF\u8FF0\u5340\u5C6C\u6027 {0} \u7121\u6548
error.missing.provider=\u627E\u4E0D\u5230\u670D\u52D9\u63D0\u4F9B\u8005: {0}
error.release.value.notnumber=\u7248\u672C {0} \u7121\u6548
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,13 +58,10 @@
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.MessageFormat;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Deque;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -101,6 +98,7 @@
import jdk.internal.joptsimple.ValueConverter;
import jdk.internal.loader.ResourceHelper;
import jdk.internal.module.ModuleHashes;
+import jdk.internal.module.ModuleHashesBuilder;
import jdk.internal.module.ModuleInfo;
import jdk.internal.module.ModuleInfoExtender;
import jdk.internal.module.ModulePath;
@@ -286,7 +284,27 @@
}
private boolean hashModules() {
- return new Hasher(options.moduleFinder).run();
+ if (options.dryrun) {
+ out.println("Dry run:");
+ }
+
+ Hasher hasher = new Hasher(options.moduleFinder);
+ hasher.computeHashes().forEach((mn, hashes) -> {
+ if (options.dryrun) {
+ out.format("%s%n", mn);
+ hashes.names().stream()
+ .sorted()
+ .forEach(name -> out.format(" hashes %s %s %s%n",
+ name, hashes.algorithm(), toHex(hashes.hashFor(name))));
+ } else {
+ try {
+ hasher.updateModuleInfo(mn, hashes);
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ }
+ });
+ return true;
}
private boolean describe() throws IOException {
@@ -377,7 +395,7 @@
// create jmod with temporary name to avoid it being examined
// when scanning the module path
Path target = options.jmodFile;
- Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
+ Path tempTarget = Files.createTempFile(target.getFileName().toString(), ".tmp");
try {
try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
jmod.write(jos);
@@ -411,7 +429,6 @@
final String osArch = options.osArch;
final String osVersion = options.osVersion;
final List<PathMatcher> excludes = options.excludes;
- final Hasher hasher = hasher();
final ModuleResolution moduleResolution = options.moduleResolution;
JmodFileWriter() { }
@@ -514,8 +531,17 @@
if (moduleVersion != null)
extender.version(moduleVersion);
- if (hasher != null) {
- ModuleHashes moduleHashes = hasher.computeHashes(descriptor.name());
+ // --hash-modules
+ if (options.modulesToHash != null) {
+ // To compute hashes, it creates a Configuration to resolve
+ // a module graph. The post-resolution check requires
+ // the packages in ModuleDescriptor be available for validation.
+ ModuleDescriptor md;
+ try (InputStream is = miSupplier.get()) {
+ md = ModuleDescriptor.read(is, () -> packages);
+ }
+
+ ModuleHashes moduleHashes = computeHashes(md);
if (moduleHashes != null) {
extender.hashes(moduleHashes);
} else {
@@ -557,50 +583,34 @@
* The jmod file is being created and does not exist in the
* given modulepath.
*/
- private Hasher hasher() {
- if (options.modulesToHash == null)
- return null;
-
- try {
- Supplier<InputStream> miSupplier = newModuleInfoSupplier();
- if (miSupplier == null) {
- throw new IOException(MODULE_INFO + " not found");
+ private ModuleHashes computeHashes(ModuleDescriptor descriptor) {
+ String mn = descriptor.name();
+ URI uri = options.jmodFile.toUri();
+ ModuleReference mref = new ModuleReference(descriptor, uri) {
+ @Override
+ public ModuleReader open() {
+ throw new UnsupportedOperationException("opening " + mn);
}
+ };
- ModuleDescriptor descriptor;
- try (InputStream in = miSupplier.get()) {
- descriptor = ModuleDescriptor.read(in);
- }
-
- URI uri = options.jmodFile.toUri();
- ModuleReference mref = new ModuleReference(descriptor, uri) {
+ // compose a module finder with the module path and also
+ // a module finder that can find the jmod file being created
+ ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
+ new ModuleFinder() {
@Override
- public ModuleReader open() {
- throw new UnsupportedOperationException();
+ public Optional<ModuleReference> find(String name) {
+ if (descriptor.name().equals(name))
+ return Optional.of(mref);
+ else return Optional.empty();
}
- };
- // compose a module finder with the module path and also
- // a module finder that can find the jmod file being created
- ModuleFinder finder = ModuleFinder.compose(options.moduleFinder,
- new ModuleFinder() {
- @Override
- public Optional<ModuleReference> find(String name) {
- if (descriptor.name().equals(name))
- return Optional.of(mref);
- else return Optional.empty();
- }
+ @Override
+ public Set<ModuleReference> findAll() {
+ return Collections.singleton(mref);
+ }
+ });
- @Override
- public Set<ModuleReference> findAll() {
- return Collections.singleton(mref);
- }
- });
-
- return new Hasher(finder);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
+ return new Hasher(mn, finder).computeHashes().get(mn);
}
/**
@@ -789,192 +799,93 @@
* Compute and record hashes
*/
private class Hasher {
- final ModuleFinder moduleFinder;
- final Map<String, Path> moduleNameToPath;
+ final Configuration configuration;
+ final ModuleHashesBuilder hashesBuilder;
final Set<String> modules;
- final Configuration configuration;
- final boolean dryrun = options.dryrun;
+ final String moduleName; // a specific module to record hashes, if set
+
+ /**
+ * This constructor is for jmod hash command.
+ *
+ * This Hasher will determine which modules to record hashes, i.e.
+ * the module in a subgraph of modules to be hashed and that
+ * has no outgoing edges. It will record in each of these modules,
+ * say `M`, with the the hashes of modules that depend upon M
+ * directly or indirectly matching the specified --hash-modules pattern.
+ */
Hasher(ModuleFinder finder) {
- this.moduleFinder = finder;
+ this(null, finder);
+ }
+
+ /**
+ * Constructs a Hasher to compute hashes.
+ *
+ * If a module name `M` is specified, it will compute the hashes of
+ * modules that depend upon M directly or indirectly matching the
+ * specified --hash-modules pattern and record in the ModuleHashes
+ * attribute in M's module-info.class.
+ *
+ * @param name name of the module to record hashes
+ * @param finder module finder for the specified --module-path
+ */
+ Hasher(String name, ModuleFinder finder) {
// Determine the modules that matches the pattern {@code modulesToHash}
- this.modules = moduleFinder.findAll().stream()
+ Set<String> roots = finder.findAll().stream()
.map(mref -> mref.descriptor().name())
.filter(mn -> options.modulesToHash.matcher(mn).find())
.collect(Collectors.toSet());
- // a map from a module name to Path of the packaged module
- this.moduleNameToPath = moduleFinder.findAll().stream()
- .map(mref -> mref.descriptor().name())
- .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn)));
-
+ // use system module path unless it creates a JMOD file for
+ // a module that is present in the system image e.g. upgradeable
+ // module
+ ModuleFinder system;
+ if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
+ system = ModuleFinder.of();
+ } else {
+ system = ModuleFinder.ofSystem();
+ }
// get a resolved module graph
Configuration config = null;
try {
- config = Configuration.empty()
- .resolveRequires(ModuleFinder.ofSystem(), moduleFinder, modules);
+ config = Configuration.empty().resolveRequires(system, finder, roots);
} catch (ResolutionException e) {
- warning("warn.module.resolution.fail", e.getMessage());
+ throw new CommandException("err.module.resolution.fail", e.getMessage());
}
+
+ this.moduleName = name;
this.configuration = config;
+
+ // filter modules resolved from the system module finder
+ this.modules = config.modules().stream()
+ .map(ResolvedModule::name)
+ .filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
+ .collect(Collectors.toSet());
+
+ this.hashesBuilder = new ModuleHashesBuilder(config, modules);
}
/**
- * This method is for jmod hash command.
+ * Returns a map of a module M to record hashes of the modules
+ * that depend upon M directly or indirectly.
*
- * Identify the base modules in the module graph, i.e. no outgoing edge
- * to any of the modules to be hashed.
+ * For jmod hash command, the returned map contains one entry
+ * for each module M that has no outgoing edges to any of the
+ * modules matching the specified --hash-modules pattern.
*
- * For each base module M, compute the hashes of all modules that depend
- * upon M directly or indirectly. Then update M's module-info.class
- * to record the hashes.
+ * Each entry represents a leaf node in a connected subgraph containing
+ * M and other candidate modules from the module graph where M's outgoing
+ * edges to any module other than the ones matching the specified
+ * --hash-modules pattern are excluded.
*/
- boolean run() {
- if (configuration == null)
- return false;
-
- // transposed graph containing the the packaged modules and
- // its transitive dependences matching --hash-modules
- Map<String, Set<String>> graph = new HashMap<>();
- for (String root : modules) {
- Deque<String> deque = new ArrayDeque<>();
- deque.add(root);
- Set<String> visited = new HashSet<>();
- while (!deque.isEmpty()) {
- String mn = deque.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- if (modules.contains(mn))
- graph.computeIfAbsent(mn, _k -> new HashSet<>());
-
- ResolvedModule resolvedModule = configuration.findModule(mn).get();
- for (ResolvedModule dm : resolvedModule.reads()) {
- String name = dm.name();
- if (!visited.contains(name)) {
- deque.push(name);
- }
-
- // reverse edge
- if (modules.contains(name) && modules.contains(mn)) {
- graph.computeIfAbsent(name, _k -> new HashSet<>()).add(mn);
- }
- }
- }
- }
- }
-
- if (dryrun)
- out.println("Dry run:");
-
- // each node in a transposed graph is a matching packaged module
- // in which the hash of the modules that depend upon it is recorded
- graph.entrySet().stream()
- .filter(e -> !e.getValue().isEmpty())
- .forEach(e -> {
- String mn = e.getKey();
- Map<String, Path> modulesForHash = e.getValue().stream()
- .collect(Collectors.toMap(Function.identity(),
- moduleNameToPath::get));
- ModuleHashes hashes = ModuleHashes.generate(modulesForHash, "SHA-256");
- if (dryrun) {
- out.format("%s%n", mn);
- hashes.names().stream()
- .sorted()
- .forEach(name -> out.format(" hashes %s %s %s%n",
- name, hashes.algorithm(), hashes.hashFor(name)));
- } else {
- try {
- updateModuleInfo(mn, hashes);
- } catch (IOException ex) {
- throw new UncheckedIOException(ex);
- }
- }
- });
- return true;
- }
-
- /**
- * Compute hashes of the specified module.
- *
- * It records the hashing modules that depend upon the specified
- * module directly or indirectly.
- */
- ModuleHashes computeHashes(String name) {
- if (configuration == null)
+ Map<String, ModuleHashes> computeHashes() {
+ if (hashesBuilder == null)
return null;
- // the transposed graph includes all modules in the resolved graph
- Map<String, Set<String>> graph = transpose();
-
- // find the modules that transitively depend upon the specified name
- Deque<String> deque = new ArrayDeque<>();
- deque.add(name);
- Set<String> mods = visitNodes(graph, deque);
-
- // filter modules matching the pattern specified --hash-modules
- // as well as itself as the jmod file is being generated
- Map<String, Path> modulesForHash = mods.stream()
- .filter(mn -> !mn.equals(name) && modules.contains(mn))
- .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get));
-
- if (modulesForHash.isEmpty())
- return null;
-
- return ModuleHashes.generate(modulesForHash, "SHA-256");
- }
-
- /**
- * Returns all nodes traversed from the given roots.
- */
- private Set<String> visitNodes(Map<String, Set<String>> graph,
- Deque<String> roots) {
- Set<String> visited = new HashSet<>();
- while (!roots.isEmpty()) {
- String mn = roots.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
- // the given roots may not be part of the graph
- if (graph.containsKey(mn)) {
- for (String dm : graph.get(mn)) {
- if (!visited.contains(dm)) {
- roots.push(dm);
- }
- }
- }
- }
+ if (moduleName != null) {
+ return hashesBuilder.computeHashes(Set.of(moduleName));
+ } else {
+ return hashesBuilder.computeHashes(modules);
}
- return visited;
- }
-
- /**
- * Returns a transposed graph from the resolved module graph.
- */
- private Map<String, Set<String>> transpose() {
- Map<String, Set<String>> transposedGraph = new HashMap<>();
- Deque<String> deque = new ArrayDeque<>(modules);
-
- Set<String> visited = new HashSet<>();
- while (!deque.isEmpty()) {
- String mn = deque.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>());
-
- ResolvedModule resolvedModule = configuration.findModule(mn).get();
- for (ResolvedModule dm : resolvedModule.reads()) {
- String name = dm.name();
- if (!visited.contains(name)) {
- deque.push(name);
- }
-
- // reverse edge
- transposedGraph.computeIfAbsent(name, _k -> new HashSet<>())
- .add(mn);
- }
- }
- }
- return transposedGraph;
}
/**
@@ -993,11 +904,11 @@
extender.write(out);
}
- private void updateModuleInfo(String name, ModuleHashes moduleHashes)
+ void updateModuleInfo(String name, ModuleHashes moduleHashes)
throws IOException
{
- Path target = moduleNameToPath.get(name);
- Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
+ Path target = moduleToPath(name);
+ Path tempTarget = Files.createTempFile(target.getFileName().toString(), ".tmp");
try {
if (target.getFileName().toString().endsWith(".jmod")) {
updateJmodFile(target, tempTarget, moduleHashes);
@@ -1075,10 +986,10 @@
}
private Path moduleToPath(String name) {
- ModuleReference mref = moduleFinder.find(name).orElseThrow(
+ ResolvedModule rm = configuration.findModule(name).orElseThrow(
() -> new InternalError("Selected module " + name + " not on module path"));
- URI uri = mref.location().get();
+ URI uri = rm.reference().location().get();
Path path = Paths.get(uri);
String fn = path.getFileName().toString();
if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
@@ -1088,34 +999,58 @@
}
}
- static class ClassPathConverter implements ValueConverter<Path> {
- static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
+ /**
+ * An abstract converter that given a string representing a list of paths,
+ * separated by the File.pathSeparator, returns a List of java.nio.Path's.
+ * Specific subclasses should do whatever validation is required on the
+ * individual path elements, if any.
+ */
+ static abstract class AbstractPathConverter implements ValueConverter<List<Path>> {
+ @Override
+ public List<Path> convert(String value) {
+ List<Path> paths = new ArrayList<>();
+ String[] pathElements = value.split(File.pathSeparator);
+ for (String pathElement : pathElements) {
+ paths.add(toPath(pathElement));
+ }
+ return paths;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Class<List<Path>> valueType() {
+ return (Class<List<Path>>)(Object)List.class;
+ }
+
+ @Override public String valuePattern() { return "path"; }
+
+ abstract Path toPath(String path);
+ }
+
+ static class ClassPathConverter extends AbstractPathConverter {
+ static final ValueConverter<List<Path>> INSTANCE = new ClassPathConverter();
@Override
- public Path convert(String value) {
+ public Path toPath(String value) {
try {
Path path = CWD.resolve(value);
if (Files.notExists(path))
throw new CommandException("err.path.not.found", path);
- if (! (Files.isDirectory(path) ||
- (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
+ if (!(Files.isDirectory(path) ||
+ (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
throw new CommandException("err.invalid.class.path.entry", path);
return path;
} catch (InvalidPathException x) {
throw new CommandException("err.path.not.valid", value);
}
}
-
- @Override public Class<Path> valueType() { return Path.class; }
-
- @Override public String valuePattern() { return "path"; }
}
- static class DirPathConverter implements ValueConverter<Path> {
- static final ValueConverter<Path> INSTANCE = new DirPathConverter();
+ static class DirPathConverter extends AbstractPathConverter {
+ static final ValueConverter<List<Path>> INSTANCE = new DirPathConverter();
@Override
- public Path convert(String value) {
+ public Path toPath(String value) {
try {
Path path = CWD.resolve(value);
if (Files.notExists(path))
@@ -1127,10 +1062,6 @@
throw new CommandException("err.path.not.valid", value);
}
}
-
- @Override public Class<Path> valueType() { return Path.class; }
-
- @Override public String valuePattern() { return "path"; }
}
static class ExtractDirPathConverter implements ValueConverter<Path> {
@@ -1142,12 +1073,6 @@
if (Files.exists(path)) {
if (!Files.isDirectory(path))
throw new CommandException("err.cannot.create.dir", path);
- } else {
- try {
- Files.createDirectories(path);
- } catch (IOException ioe) {
- throw new CommandException("err.cannot.create.dir", path);
- }
}
return path;
} catch (InvalidPathException x) {
@@ -1316,22 +1241,19 @@
options = new Options();
parser.formatHelpWith(new JmodHelpFormatter(options));
- OptionSpec<Path> classPath
+ OptionSpec<List<Path>> classPath
= parser.accepts("class-path", getMessage("main.opt.class-path"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(ClassPathConverter.INSTANCE);
- OptionSpec<Path> cmds
+ OptionSpec<List<Path>> cmds
= parser.accepts("cmds", getMessage("main.opt.cmds"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> config
+ OptionSpec<List<Path>> config
= parser.accepts("config", getMessage("main.opt.config"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
OptionSpec<Path> dir
@@ -1359,22 +1281,19 @@
OptionSpec<Void> helpExtra
= parser.accepts("help-extra", getMessage("main.opt.help-extra"));
- OptionSpec<Path> headerFiles
+ OptionSpec<List<Path>> headerFiles
= parser.accepts("header-files", getMessage("main.opt.header-files"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> libs
+ OptionSpec<List<Path>> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> legalNotices
+ OptionSpec<List<Path>> legalNotices
= parser.accepts("legal-notices", getMessage("main.opt.legal-notices"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
@@ -1383,17 +1302,15 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
- OptionSpec<Path> manPages
+ OptionSpec<List<Path>> manPages
= parser.accepts("man-pages", getMessage("main.opt.man-pages"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
- OptionSpec<Path> modulePath
+ OptionSpec<List<Path>> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
.withRequiredArg()
- .withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);
OptionSpec<Version> moduleVersion
@@ -1452,48 +1369,48 @@
}
if (opts.has(classPath))
- options.classpath = opts.valuesOf(classPath);
+ options.classpath = getLastElement(opts.valuesOf(classPath));
if (opts.has(cmds))
- options.cmds = opts.valuesOf(cmds);
+ options.cmds = getLastElement(opts.valuesOf(cmds));
if (opts.has(config))
- options.configs = opts.valuesOf(config);
+ options.configs = getLastElement(opts.valuesOf(config));
if (opts.has(dir))
- options.extractDir = opts.valueOf(dir);
+ options.extractDir = getLastElement(opts.valuesOf(dir));
if (opts.has(dryrun))
options.dryrun = true;
if (opts.has(excludes))
- options.excludes = opts.valuesOf(excludes);
+ options.excludes = opts.valuesOf(excludes); // excludes is repeatable
if (opts.has(libs))
- options.libs = opts.valuesOf(libs);
+ options.libs = getLastElement(opts.valuesOf(libs));
if (opts.has(headerFiles))
- options.headerFiles = opts.valuesOf(headerFiles);
+ options.headerFiles = getLastElement(opts.valuesOf(headerFiles));
if (opts.has(manPages))
- options.manPages = opts.valuesOf(manPages);
+ options.manPages = getLastElement(opts.valuesOf(manPages));
if (opts.has(legalNotices))
- options.legalNotices = opts.valuesOf(legalNotices);
+ options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
if (opts.has(modulePath)) {
- Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
+ Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
options.moduleFinder = new ModulePath(Runtime.version(), true, dirs);
}
if (opts.has(moduleVersion))
- options.moduleVersion = opts.valueOf(moduleVersion);
+ options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
if (opts.has(mainClass))
- options.mainClass = opts.valueOf(mainClass);
+ options.mainClass = getLastElement(opts.valuesOf(mainClass));
if (opts.has(osName))
- options.osName = opts.valueOf(osName);
+ options.osName = getLastElement(opts.valuesOf(osName));
if (opts.has(osArch))
- options.osArch = opts.valueOf(osArch);
+ options.osArch = getLastElement(opts.valuesOf(osArch));
if (opts.has(osVersion))
- options.osVersion = opts.valueOf(osVersion);
+ options.osVersion = getLastElement(opts.valuesOf(osVersion));
if (opts.has(warnIfResolved))
- options.moduleResolution = opts.valueOf(warnIfResolved);
+ options.moduleResolution = getLastElement(opts.valuesOf(warnIfResolved));
if (opts.has(doNotResolveByDefault)) {
if (options.moduleResolution == null)
options.moduleResolution = ModuleResolution.empty();
options.moduleResolution = options.moduleResolution.withDoNotResolveByDefault();
}
if (opts.has(hashModules)) {
- options.modulesToHash = opts.valueOf(hashModules);
+ options.modulesToHash = getLastElement(opts.valuesOf(hashModules));
// if storing hashes then the module path is required
if (options.moduleFinder == null)
throw new CommandException("err.modulepath.must.be.specified")
@@ -1531,6 +1448,13 @@
throw new CommandException("err.classpath.must.be.specified").showUsage(true);
if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
throw new CommandException("err.invalid.main-class", options.mainClass);
+ if (options.mode.equals(Mode.EXTRACT) && options.extractDir != null) {
+ try {
+ Files.createDirectories(options.extractDir);
+ } catch (IOException ioe) {
+ throw new CommandException("err.cannot.create.dir", options.extractDir);
+ }
+ }
} catch (OptionException e) {
throw new CommandException(e.getMessage());
}
@@ -1558,6 +1482,12 @@
return true;
}
+ static <E> E getLastElement(List<E> list) {
+ if (list.size() == 0)
+ throw new InternalError("Unexpected 0 list size");
+ return list.get(list.size() - 1);
+ }
+
private void reportError(String message) {
out.println(getMessage("error.prefix") + " " + message);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Tue Jan 24 00:30:23 2017 +0100
@@ -108,9 +108,9 @@
err.invalid.dryrun.option=--dry-run can only be used with hash mode
err.module.descriptor.not.found=Module descriptor not found
err.missing.export.or.open.packages=Packages that are exported or open in {0} are not present: {1}
+err.module.resolution.fail=Resolution failed: {0}
warn.invalid.arg=Invalid classname or pathname not exist: {0}
warn.no.module.hashes=No hashes recorded: no module specified for hashing depends on {0}
-warn.module.resolution.fail=No hashes recorded: {0}
warn.ignore.entry=ignoring entry {0}, in section {1}
warn.ignore.duplicate.entry=ignoring duplicate entry {0}, in section {1}
--- a/jdk/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c Tue Jan 24 00:30:23 2017 +0100
@@ -418,7 +418,6 @@
(JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
jlong address, jint length, jboolean peek) {
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
ssize_t rv = 0;
jlong *addr = jlong_to_ptr(address);
struct iovec iov[1];
@@ -429,7 +428,7 @@
/* Set up the msghdr structure for receiving */
memset(msg, 0, sizeof (*msg));
msg->msg_name = &sa;
- msg->msg_namelen = sa_len;
+ msg->msg_namelen = sizeof(sa);
iov->iov_base = addr;
iov->iov_len = length;
msg->msg_iov = iov;
@@ -538,7 +537,7 @@
jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
jboolean unordered, jint ppid) {
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
+ int sa_len = 0;
ssize_t rv = 0;
jlong *addr = jlong_to_ptr(address);
struct iovec iov[1];
@@ -555,13 +554,12 @@
* Association already existing, assocId != -1, targetAddress = preferred addr
*/
if (targetAddress != NULL /*&& assocId <= 0*/) {
- if (NET_InetAddressToSockaddr(env, targetAddress, targetPort, &sa.sa,
+ if (NET_InetAddressToSockaddr(env, targetAddress, targetPort, &sa,
&sa_len, JNI_TRUE) != 0) {
return IOS_THROWN;
}
} else {
- memset(&sa, '\x0', sa_len);
- sa_len = 0;
+ memset(&sa, '\x0', sizeof(sa));
}
/* Set up the msghdr structure for sending */
--- a/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c Tue Jan 24 00:30:23 2017 +0100
@@ -211,22 +211,22 @@
(JNIEnv *env, jclass klass, jint fd, jobjectArray addrs, jint port,
jint addrsLength, jboolean add, jboolean preferIPv6) {
SOCKETADDRESS *sap, *tmpSap;
- int i, sa_len = sizeof(SOCKETADDRESS);
+ int i;
jobject ia;
if (addrsLength < 1)
return;
- if ((sap = calloc(addrsLength, sa_len)) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
+ if ((sap = calloc(addrsLength, sizeof(SOCKETADDRESS))) == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
return;
}
tmpSap = sap;
for (i = 0; i < addrsLength; i++) {
ia = (*env)->GetObjectArrayElement(env, addrs, i);
- if (NET_InetAddressToSockaddr(env, ia, port, (struct sockaddr*)tmpSap,
- &sa_len, preferIPv6) != 0) {
+ if (NET_InetAddressToSockaddr(env, ia, port, tmpSap, NULL,
+ preferIPv6) != 0) {
free(sap);
return;
}
@@ -262,11 +262,11 @@
Java_sun_nio_ch_sctp_SctpNet_connect0
(JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) {
SOCKETADDRESS sa;
- int sa_len = sizeof(SOCKETADDRESS);
+ int sa_len = 0;
int rv;
- if (NET_InetAddressToSockaddr(env, iao, port, &sa.sa,
- &sa_len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
+ JNI_TRUE) != 0) {
return IOS_THROWN;
}
@@ -311,8 +311,7 @@
}
}
-void initializeISA
- (JNIEnv* env) {
+void initializeISA(JNIEnv* env) {
if (isaCls == 0) {
jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
CHECK_NULL(c);
@@ -325,8 +324,7 @@
}
}
-jobject SockAddrToInetSocketAddress
- (JNIEnv *env, struct sockaddr* sap) {
+jobject SockAddrToInetSocketAddress(JNIEnv *env, SOCKETADDRESS *sap) {
int port = 0;
jobject ia = NET_SockaddrToInetAddress(env, sap, &port);
@@ -347,9 +345,9 @@
* Signature: (I)[Ljava/net/SocketAddress;
*/
JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getLocalAddresses0
- (JNIEnv *env, jclass klass, jint fd) {
+ (JNIEnv *env, jclass klass, jint fd)
+{
void *addr_buf, *laddr;
- struct sockaddr* sap;
int i, addrCount;
jobjectArray isaa;
@@ -377,38 +375,35 @@
}
laddr = addr_buf;
- for (i=0; i<addrCount; i++) {
+ for (i = 0; i < addrCount; i++) {
int port = 0;
- jobject isa = NULL, ia;
- sap = (struct sockaddr*)addr_buf;
- ia = NET_SockaddrToInetAddress(env, sap, &port);
+ jobject ia, isa = NULL;
+ ia = NET_SockaddrToInetAddress(env, (SOCKETADDRESS *)addr_buf, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
if (isa == NULL)
break;
(*env)->SetObjectArrayElement(env, isaa, i, isa);
- if (sap->sa_family == AF_INET)
- addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
+ if (((struct sockaddr *)addr_buf)->sa_family == AF_INET)
+ addr_buf = ((struct sockaddr_in *)addr_buf) + 1;
else
- addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
+ addr_buf = ((struct sockaddr_in6 *)addr_buf) + 1;
}
nio_sctp_freeladdrs(laddr);
return isaa;
}
-jobjectArray getRemoteAddresses
- (JNIEnv *env, jint fd, sctp_assoc_t id) {
+jobjectArray getRemoteAddresses(JNIEnv *env, jint fd, sctp_assoc_t id) {
void *addr_buf, *paddr;
- struct sockaddr* sap;
int i, addrCount;
jobjectArray isaa;
#if __solaris__
if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {
#else /* __linux__ */
- if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr**)&addr_buf)) == -1) {
+ if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr **)&addr_buf)) == -1) {
#endif
handleSocketError(env, errno);
return NULL;
@@ -429,25 +424,23 @@
}
paddr = addr_buf;
- for (i=0; i<addrCount; i++) {
- jobject ia, isa = NULL;
+ for (i = 0; i < addrCount; i++) {
int port = 0;
- sap = (struct sockaddr*)addr_buf;
- ia = NET_SockaddrToInetAddress(env, sap, &port);
+ jobject ia, isa = NULL;
+ ia = NET_SockaddrToInetAddress(env, (SOCKETADDRESS *)addr_buf, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
if (isa == NULL)
break;
(*env)->SetObjectArrayElement(env, isaa, i, isa);
- if (sap->sa_family == AF_INET)
- addr_buf = ((struct sockaddr_in*)addr_buf) + 1;
+ if (((struct sockaddr *)addr_buf)->sa_family == AF_INET)
+ addr_buf = ((struct sockaddr_in *)addr_buf) + 1;
else
- addr_buf = ((struct sockaddr_in6*)addr_buf) + 1;
+ addr_buf = ((struct sockaddr_in6 *)addr_buf) + 1;
}
nio_sctp_freepaddrs(paddr);
-
return isaa;
}
@@ -579,7 +572,6 @@
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
struct sctp_setprim prim;
unsigned int prim_len = sizeof(prim);
- struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
prim.ssp_assoc_id = assocId;
@@ -589,7 +581,7 @@
return NULL;
}
- return SockAddrToInetSocketAddress(env, sap);
+ return SockAddrToInetSocketAddress(env, (SOCKETADDRESS *)&prim.ssp_addr);
}
/*
@@ -600,11 +592,10 @@
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {
struct sctp_setprim prim;
- struct sockaddr* sap = (struct sockaddr*)&prim.ssp_addr;
- int sap_len = sizeof(sap);
- if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
- &sap_len, JNI_TRUE) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port,
+ (SOCKETADDRESS *)&prim.ssp_addr,
+ NULL, JNI_TRUE) != 0) {
return;
}
@@ -625,18 +616,17 @@
(JNIEnv *env, jclass klass, jint fd, jint assocId,
jobject iaObj, jint port, jboolean preferIPv6) {
struct sctp_setpeerprim prim;
- struct sockaddr* sap = (struct sockaddr*)&prim.sspp_addr;
- int sap_len = sizeof(sap);
- if (NET_InetAddressToSockaddr(env, iaObj, port, sap,
- &sap_len, preferIPv6) != 0) {
+ if (NET_InetAddressToSockaddr(env, iaObj, port,
+ (SOCKETADDRESS *)&prim.sspp_addr,
+ NULL, preferIPv6) != 0) {
return;
}
prim.sspp_assoc_id = assocId;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, &prim,
- sizeof(prim)) < 0) {
+ sizeof(prim)) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.setPeerPrimAddrOption0");
}
--- a/jdk/test/ProblemList.txt Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/ProblemList.txt Tue Jan 24 00:30:23 2017 +0100
@@ -1,6 +1,6 @@
###########################################################################
#
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, 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
@@ -141,8 +141,6 @@
# jdk_io
-java/io/pathNames/GeneralWin32.java 8156595 windows-all
-
############################################################################
# jdk_management
@@ -203,8 +201,6 @@
sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-all
-java/rmi/registry/readTest/readTest.sh 7146543 generic-all
-
############################################################################
# jdk_security
@@ -262,6 +258,8 @@
tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java 8169971 windows-x64
+tools/jmod/JmodTest.java 8172870 windows-all
+
############################################################################
# jdk_jdi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/NormalToIconified/NormalToIconifiedTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,105 @@
+/*
+ * 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 8171949
+ * @summary Tests that bitwise mask is set and state listener is notified during state transition.
+ * @author Dmitry Markov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main NormalToIconifiedTest
+ */
+
+import java.awt.Frame;
+import java.awt.Robot;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowStateListener;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import test.java.awt.regtesthelpers.Util;
+
+public class NormalToIconifiedTest {
+ private static final AtomicBoolean listenerNotified = new AtomicBoolean(false);
+
+ public static void main(String[] args) {
+ Robot robot = Util.createRobot();
+
+ Frame testFrame = new Frame("Test Frame");
+ testFrame.setSize(200, 200);
+ testFrame.addWindowStateListener(new WindowStateListener() {
+ @Override
+ public void windowStateChanged(WindowEvent e) {
+ listenerNotified.set(true);
+ synchronized (listenerNotified) {
+ listenerNotified.notifyAll();
+ }
+ }
+ });
+ testFrame.setVisible(true);
+
+ Frame mainFrame = new Frame("Main Frame");
+ mainFrame.setSize(200, 200);
+ mainFrame.setLocationRelativeTo(null);
+ mainFrame.setVisible(true);
+
+ Util.waitForIdle(robot);
+
+ try {
+ Util.clickOnComp(mainFrame, robot);
+ Util.waitForIdle(robot);
+
+ // NORMAL -> ICONIFIED
+ listenerNotified.set(false);
+ testFrame.setExtendedState(Frame.ICONIFIED);
+ Util.waitForIdle(robot);
+
+ Util.waitForCondition(listenerNotified, 2000);
+ if (!listenerNotified.get()) {
+ throw new RuntimeException("Test FAILED! Window state listener was not notified during NORMAL to" +
+ "ICONIFIED transition");
+ }
+ if (testFrame.getExtendedState() != Frame.ICONIFIED) {
+ throw new RuntimeException("Test FAILED! Frame is not in ICONIFIED state");
+ }
+
+ // ICONIFIED -> NORMAL
+ listenerNotified.set(false);
+ testFrame.setExtendedState(Frame.NORMAL);
+ Util.waitForIdle(robot);
+
+ Util.waitForCondition(listenerNotified, 2000);
+ if (!listenerNotified.get()) {
+ throw new RuntimeException("Test FAILED! Window state listener was not notified during ICONIFIED to" +
+ "NORMAL transition");
+ }
+ if (testFrame.getExtendedState() != Frame.NORMAL) {
+ throw new RuntimeException("Test FAILED! Frame is not in NORMAL state");
+ }
+ } finally {
+ testFrame.dispose();
+ mainFrame.dispose();
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,70 @@
+/*
+ * 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 8171952
+ * @summary Tests that getMousePosition() returns null for obscured component.
+ * @author Dmitry Markov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ObscuredFrameTest
+ */
+
+import java.awt.*;
+
+import test.java.awt.regtesthelpers.Util;
+
+public class ObscuredFrameTest {
+ public static void main(String[] args) {
+ Robot robot = Util.createRobot();
+
+ Frame frame = new Frame("Obscured Frame");
+ frame.setSize(200, 200);
+ frame.setLocationRelativeTo(null);
+ Button button = new Button("Button");
+ frame.add(button);
+
+ Dialog dialog = new Dialog(frame, "Visible Dialog", false);
+ dialog.setSize(200, 200);
+ dialog.setLocationRelativeTo(null);
+ dialog.setVisible(true);
+
+ frame.setVisible(true);
+
+ Util.waitForIdle(robot);
+
+ Util.pointOnComp(button, robot);
+ Util.waitForIdle(robot);
+
+ try {
+ if (button.getMousePosition() != null) {
+ throw new RuntimeException("Test Failed! Mouse position is not null for obscured component.");
+ }
+ } finally {
+ frame.dispose();
+ dialog.dispose();
+ }
+ }
+}
+
--- a/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -23,7 +23,7 @@
/* @test
@key headful
- @bug 8166897
+ @bug 8166897 8167652
@summary Some font overlap in the Optionpane dialog.
@run main ChangeWindowResizabiltyTest
*/
@@ -34,41 +34,75 @@
import java.awt.Frame;
import java.awt.Panel;
import java.awt.Robot;
+import java.awt.Point;
public class ChangeWindowResizabiltyTest {
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
for(int i = 0; i < 10; i++) {
Dialog dialog = new Dialog((Frame) null);
+ dialog.setLocation(100, 100);
Component panel = new Panel();
panel.setPreferredSize(new Dimension(200, 100));
dialog.add(panel);
dialog.pack();
dialog.setVisible(true);
+ robot.waitForIdle();
+ robot.delay(200);
+
+ Point frameLoc = dialog.getLocationOnScreen();
+ Point contentLoc = panel.getLocationOnScreen();
+
+ System.out.println("Decor location " + frameLoc);
+ System.out.println("Content location " + contentLoc);
dialog.setResizable(false);
robot.waitForIdle();
robot.delay(200);
- System.out.println(panel.getLocationOnScreen());
- System.out.println(dialog.getLocationOnScreen());
+ Point l = dialog.getLocationOnScreen();
+ if (!l.equals(frameLoc)) {
+ dialog.dispose();
+ throw new RuntimeException("Decorated frame location moved " +
+ "after setResizable(false)" + l);
+ }
+
+ l = panel.getLocationOnScreen();
+ if (!l.equals(contentLoc)) {
+ dialog.dispose();
+ throw new RuntimeException("Content location moved after " +
+ "setResizable(false)" + l);
+ }
+
if (panel.getLocationOnScreen().y <
- dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+ dialog.getLocationOnScreen().y + dialog.getInsets().top) {
dialog.dispose();
throw new RuntimeException(
- "Wrong content position after setResizable(false)");
+ "Wrong content position after setResizable(false)");
}
dialog.setResizable(true);
robot.waitForIdle();
robot.delay(200);
- System.out.println(panel.getLocationOnScreen());
- System.out.println(dialog.getLocationOnScreen());
+
+ l = dialog.getLocationOnScreen();
+ if (!l.equals(frameLoc)) {
+ dialog.dispose();
+ throw new RuntimeException("Decorated frame location moved " +
+ "after setResizable(true)" + l);
+ }
+
+ l = panel.getLocationOnScreen();
+ if (!l.equals(contentLoc)) {
+ dialog.dispose();
+ throw new RuntimeException("Content location moved after " +
+ "setResizable(true)" + l);
+ }
if (panel.getLocationOnScreen().y <
- dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+ dialog.getLocationOnScreen().y + dialog.getInsets().top) {
dialog.dispose();
throw new RuntimeException(
- "Wrong content position after setResizable(true)");
+ "Wrong content position after setResizable(true)");
}
dialog.dispose();
--- a/jdk/test/java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -22,7 +22,6 @@
*/
import sun.awt.image.MultiResolutionToolkitImage;
-import sun.java2d.SunGraphics2D;
import javax.swing.*;
import java.awt.*;
@@ -37,7 +36,6 @@
* @summary [macosx] Drag image of TransferHandler does not honor
* MultiResolutionImage
* @modules java.desktop/sun.awt.image
- * java.desktop/sun.java2d
* @run main MultiResolutionDragImageTest TEST_DRAG
*/
public class MultiResolutionDragImageTest {
@@ -126,30 +124,11 @@
return Math.abs(n - m) <= 50;
}
- private static float getScaleFactor() {
-
- final Dialog dialog = new Dialog((Window) null);
- dialog.setSize(100, 100);
- dialog.setModal(true);
- final float[] scaleFactors = new float[1];
- Panel panel = new Panel() {
-
- @Override
- public void paint(Graphics g) {
- float scaleFactor = 1;
- if (g instanceof SunGraphics2D) {
- scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale();
- }
- scaleFactors[0] = scaleFactor;
- dialog.setVisible(false);
- }
- };
-
- dialog.add(panel);
- dialog.setVisible(true);
- dialog.dispose();
-
- return scaleFactors[0];
+ static float getScaleFactor() {
+ return (float) GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration().
+ getDefaultTransform().getScaleX();
}
private static Image createMultiResolutionImage() {
--- a/jdk/test/java/awt/font/GlyphVector/TestLayoutFlags.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/font/GlyphVector/TestLayoutFlags.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -23,7 +23,7 @@
/* @test
- @bug 4328745 5090704
+ @bug 4328745 5090704 8166111
@summary exercise getLayoutFlags, getGlyphCharIndex, getGlyphCharIndices
*/
@@ -82,7 +82,7 @@
test("latin", latinGV, GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
test("hebrew", hebrewGV, GlyphVector.FLAG_RUN_RTL |
GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
- test("arabic", arabicGV, GlyphVector.FLAG_RUN_RTL |
+ test("arabic", arabicGV, GlyphVector.FLAG_COMPLEX_GLYPHS |
GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
test("hindi", hindiGV, GlyphVector.FLAG_COMPLEX_GLYPHS |
GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/Raster/TestChildRasterOp.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, 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 8130737 8172559
+ * @summary test no exception rasterop for child raster with non-zero offset
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class TestChildRasterOp {
+
+ private static AffineTransform at = new AffineTransform();
+ private static final AffineTransformOp rop =
+ new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ private static int[] offsets = {0};
+
+ public static void main(String[] args) {
+ testByteRaster();
+ testShortRaster();
+ testIntRaster();
+ }
+
+ private static void testByteRaster() {
+ WritableRaster srcRaster, dstRaster;
+
+ byte[] pixels =
+ { 11, 12, 13, 14,
+ 21, 22, 23, 24,
+ 31, 32, 33, 34,
+ 41, 42, 43, 44 };
+
+ DataBuffer db = new DataBufferByte(pixels, pixels.length);
+ srcRaster =
+ Raster.createInterleavedRaster(db, 4, 4, 4, 1, offsets, null);
+ srcRaster = srcRaster.createWritableChild(1, 1, 3, 3, 0, 0, null);
+ dstRaster = rop.filter(srcRaster, null);
+ }
+
+ private static void testShortRaster() {
+ WritableRaster srcRaster, dstRaster;
+
+ short[] pixels =
+ { 11, 12, 13, 14,
+ 21, 22, 23, 24,
+ 31, 32, 33, 34,
+ 41, 42, 43, 44 };
+
+ DataBuffer db = new DataBufferUShort(pixels, pixels.length);
+ srcRaster =
+ Raster.createInterleavedRaster(db, 4, 4, 4, 1, offsets, null);
+ srcRaster = srcRaster.createWritableChild(1, 1, 3, 3, 0, 0, null);
+ dstRaster = rop.filter(srcRaster, null);
+ }
+
+ private static void testIntRaster() {
+ WritableRaster srcRaster, dstRaster;
+
+ int[] pixels =
+ { 11, 12, 13, 14,
+ 21, 22, 23, 24,
+ 31, 32, 33, 34,
+ 41, 42, 43, 44 };
+
+ DataBuffer db = new DataBufferInt(pixels, pixels.length);
+ srcRaster =
+ Raster.createPackedRaster(db, 4, 4, 4, offsets, null);
+ srcRaster = srcRaster.createWritableChild(1, 1, 3, 3, 0, 0, null);
+ dstRaster = rop.filter(srcRaster, null);
+ }
+}
--- a/jdk/test/java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java Tue Jan 24 00:30:23 2017 +0100
@@ -24,16 +24,28 @@
/*
* @test
* @key headful
- * @bug 7108598
+ * @bug 7108598 8172009
* @summary Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods deadlock
* @library ../../regtesthelpers
* @author Oleg Pekhovskiy
* @build Util
- * @run main/timeout=20 PaintSetEnabledDeadlock
+ * @run main PaintSetEnabledDeadlock
*/
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.Button;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Image;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
import test.java.awt.regtesthelpers.Util;
public class PaintSetEnabledDeadlock extends Frame {
--- a/jdk/test/java/awt/print/PrinterJob/BannerTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/print/PrinterJob/BannerTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 6575247
+ * @bug 6575247 8170579
* @summary Verifies if Banner page is printed
* @requires (os.family == "linux" | os.family == "solaris")
* @run main/manual BannerTest
@@ -39,6 +39,9 @@
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
+import javax.print.PrintService;
+import javax.print.attribute.standard.JobSheets;
+import javax.print.attribute.standard.SheetCollate;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
@@ -50,8 +53,18 @@
private static Thread mainThread;
private static boolean testPassed;
private static boolean testGeneratedInterrupt;
+ private static volatile PrinterJob job;
public static void main(String[] args) throws Exception {
+ job = PrinterJob.getPrinterJob();
+ PrintService prtSrv = job.getPrintService();
+ if (job.getPrintService() == null) {
+ System.out.println("No printers. Test cannot continue");
+ return;
+ }
+ if (!prtSrv.isAttributeCategorySupported(JobSheets.class)) {
+ return;
+ }
SwingUtilities.invokeAndWait(() -> {
doTest(BannerTest::printTest);
});
@@ -69,11 +82,6 @@
}
private static void printTest() {
- PrinterJob job = PrinterJob.getPrinterJob();
- if (job.getPrintService() == null) {
- System.out.println("No printers. Test cannot continue");
- return;
- }
job.setPrintable(new BannerTest());
if(job.printDialog()) {
try {
--- a/jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java Tue Jan 24 00:30:23 2017 +0100
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 8165947
+ * @bug 8165947 8170579
* @summary Verifies System default banner page option is honoured by jdk
* @requires (os.family == "linux" | os.family == "solaris")
* @run main/manual TestCheckSystemDefaultBannerOption
@@ -38,6 +38,7 @@
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
+import javax.print.PrintService;
import javax.print.attribute.standard.JobSheets;
import javax.swing.JButton;
import javax.swing.JDialog;
@@ -56,10 +57,15 @@
public static void main (String[] args) throws Exception {
job = PrinterJob.getPrinterJob();
- if (job.getPrintService() == null) {
+ PrintService prtSrv = job.getPrintService();
+ if (prtSrv == null) {
System.out.println("No printers. Test cannot continue");
return;
}
+ // do not run the test if JobSheet category is not supported
+ if (!prtSrv.isAttributeCategorySupported(JobSheets.class)) {
+ return;
+ }
// check system default banner option and let user know what to expect
JobSheets js = (JobSheets)job.getPrintService().
getDefaultAttributeValue(JobSheets.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/File/WinDirRelative.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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 8153250
+ * @summary Tests that files are correctly listed for a directory-relative path
+ * @requires (os.family == "windows")
+ */
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WinDirRelative {
+ private static final char COLON = ':';
+ private static final String BASENAME = "TestFile_";
+ private static final String EXTENSION = ".txt";
+ private static final int NUM_FILES = 10;
+
+ private static boolean isLetter(char c) {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
+ }
+
+ public static void main(String[] args) throws Throwable {
+ // Get the working directory which is also the default
+ // directory for the current drive.
+ String userDir = System.getProperty("user.dir");
+
+ // Test only if a leading drive letter is found
+ if (isLetter(userDir.charAt(0)) && userDir.charAt(1) == COLON) {
+ // Create some empty files
+ List<String> filenames = new ArrayList<String>(NUM_FILES);
+ for (int i = 0; i < NUM_FILES; i++) {
+ String filename = BASENAME + i + EXTENSION;
+ filenames.add(filename);
+ File f = new File(filename);
+ f.createNewFile();
+ f.deleteOnExit();
+ System.out.printf("Created %s (%s)%n", filename,
+ f.getAbsolutePath());
+ }
+
+ // List files and verify that the ones with recognized names exist.
+ String prefix = userDir.substring(0, 2);
+ File p = new File(prefix);
+ int failures = 0;
+ int successes = 0;
+ for (File f : p.listFiles()) {
+ if (f.getName().toString().startsWith(BASENAME)) {
+ if (!f.exists()) {
+ System.err.printf("%s (%s) does not exist%n", f,
+ f.getAbsolutePath());
+ failures++;
+ } else {
+ successes++;
+ }
+ }
+ }
+
+ // Fail if there was an existence test failure or if not
+ // enough of the created files were found
+ boolean testFailed = false;
+ if (failures > 0) {
+ System.err.println("Existence check failed");
+ testFailed = true;
+ }
+ if (successes != NUM_FILES) {
+ System.err.println("Count check failed");
+ testFailed = true;
+ }
+ if (testFailed) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+ }
+}
--- a/jdk/test/java/io/File/createTempFile/Patterns.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/io/File/createTempFile/Patterns.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 4152178
+ @bug 4152178 8152272
@summary Check various temp-file prefix/suffix cases */
import java.io.File;
@@ -66,6 +66,7 @@
cky("xxx", "");
cky("xxx", "y");
cky("xxx", ".y");
+ cky("xyz", "Directory" + System.getProperty("file.separator"));
}
}
--- a/jdk/test/java/io/pathNames/General.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/io/pathNames/General.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -40,6 +40,7 @@
private static int gensymCounter = 0;
protected static final String userDir = System.getProperty("user.dir");
+ protected static final String workSubDir = "tmp";
protected static String baseDir = null;
protected static String relative = null;
@@ -60,7 +61,10 @@
* direct or indirect calling) in a whole test.
*/
protected static void initTestData(int depth) throws IOException {
- File parent = new File(userDir);
+ File parent = new File(userDir + File.separator + workSubDir);
+ if (!parent.mkdir()) {
+ throw new IOException("Fail to create directory: " + parent);
+ }
for (int i = 0; i < depth; i++) {
File tmp = new File(parent, gensym());
tmp.createNewFile();
--- a/jdk/test/java/io/pathNames/GeneralWin32.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/io/pathNames/GeneralWin32.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -53,7 +53,8 @@
private static void checkCaseLookup() throws IOException {
/* Use long names here to avoid 8.3 format, which Samba servers often
force to lowercase */
- File d = new File("XyZzY0123", "FOO_bar_BAZ");
+ File r = new File (workSubDir, "XyZzY0123");
+ File d = new File(r, "FOO_bar_BAZ");
File f = new File(d, "GLORPified");
if (!f.exists()) {
if (!d.exists()) {
@@ -74,9 +75,9 @@
case of filenames, rather than just using the input case */
File y = new File(userDir, f.getPath());
String ans = y.getPath();
- check(ans, "XyZzY0123\\FOO_bar_BAZ\\GLORPified");
- check(ans, "xyzzy0123\\foo_bar_baz\\glorpified");
- check(ans, "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED");
+ check(ans, workSubDir + File.separator + "XyZzY0123\\FOO_bar_BAZ\\GLORPified");
+ check(ans, workSubDir + File.separator + "xyzzy0123\\foo_bar_baz\\glorpified");
+ check(ans, workSubDir + File.separator + "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED");
}
private static void checkWild(File f) throws Exception {
@@ -125,20 +126,19 @@
throw new RuntimeException("Can't find an active drive");
}
- private static void checkDrive(int depth, char drive, boolean exists)
+ private static void checkDrive(int depth, String drive, boolean exists)
throws Exception
{
- String d = drive + ":";
- File df = new File(d);
- String ans = exists ? df.getAbsolutePath() : d;
+ File df = new File(drive);
+ String ans = exists ? df.getAbsolutePath() : drive;
if (!ans.endsWith("\\"))
ans = ans + "\\";
- checkNames(depth, false, ans, d);
+ checkNames(depth, false, ans, drive);
}
private static void checkDrivePaths(int depth) throws Exception {
- checkDrive(depth, findActiveDrive(), true);
- checkDrive(depth, findInactiveDrive(), false);
+ checkDrive(depth, findActiveDrive() + ":" + workSubDir + File.separator, true);
+ checkDrive(depth, findInactiveDrive() + ":", false);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLConnection/SetDefaultUseCaches.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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 8163449
+ * @summary Allow per protocol setting for URLConnection defaultUseCaches
+ * @run main/othervm SetDefaultUseCaches
+ */
+
+import java.net.*;
+import java.io.*;
+
+public class SetDefaultUseCaches {
+ static void testAssert(boolean value, boolean comparator) {
+ if (value != comparator) {
+ System.err.println("Expected " + comparator + " Got " + value);
+ throw new RuntimeException("Test failed:");
+ } else
+ System.err.println("OK");
+ }
+
+ public static void main(String s[]) throws Exception {
+ URL url = new URL("http://www.foo.com/");
+ URL url1 = new URL("file:///a/b.txt");
+
+ // check default default is true
+ URLConnection urlc = url.openConnection();
+ testAssert(urlc.getDefaultUseCaches(), true);
+
+ // set default for http to false and check
+ URLConnection.setDefaultUseCaches("HTTP", false);
+
+ urlc = url.openConnection();
+ testAssert(urlc.getDefaultUseCaches(), true);
+ testAssert(urlc.getUseCaches(), false);
+ testAssert(URLConnection.getDefaultUseCaches("http"), false);
+
+ URLConnection urlc1 = url1.openConnection();
+ testAssert(urlc1.getDefaultUseCaches(), true);
+
+ // set default default to false and check other values the same
+ urlc.setDefaultUseCaches(false);
+ urlc1.setDefaultUseCaches("fiLe", true);
+ testAssert(urlc1.getDefaultUseCaches(), false);
+ testAssert(URLConnection.getDefaultUseCaches("fiLE"), true);
+ }
+}
--- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,9 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary JavaVM RMID TestSecurityManager
+ * java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider RegistryVM RMIRegistryRunner
+ * TestSecurityManager
* @run main/othervm AltSecurityManager
*/
@@ -44,7 +46,6 @@
* if registry and rmid take too long to exit.
*/
public class AltSecurityManager implements Runnable {
- private final int regPort;
// variable to hold registry and rmid children
static JavaVM vm = null;
@@ -57,31 +58,34 @@
private static final long TIME_OUT =
(long)(15000 * TestLibrary.getTimeoutFactor());
- public AltSecurityManager(int port) {
- if (port <= 0) {
- TestLibrary.bomb("Port must be greater than 0.");
- }
-
- this.regPort = port;
- }
-
public void run() {
try {
if (utilityToStart.equals(REGISTRY_IMPL)) {
- vm = new JavaVM(utilityToStart,
- " -Djava.security.manager=TestSecurityManager",
- Integer.toString(regPort));
+ vm = RegistryVM.createRegistryVMWithRunner(
+ "RMIRegistryRunner",
+ "-Djava.security.manager=TestSecurityManager");
} else if (utilityToStart.contains(ACTIVATION)) {
- vm = new JavaVM(utilityToStart,
- " -Djava.security.manager=TestSecurityManager",
- "-port " + Integer.toString(regPort));
+ vm = RMID.createRMIDOnEphemeralPortWithOptions(
+ "-Djava.security.manager=TestSecurityManager");
} else {
TestLibrary.bomb("Utility to start must be " + REGISTRY_IMPL +
" or " + ACTIVATION);
}
System.err.println("starting " + utilityToStart);
- vm.execute();
+ try {
+ vm.start();
+ throw new RuntimeException("Expected exception did not occur!");
+ } catch (Exception expected) {
+ int exit = vm.waitFor();
+ if (exit != TestSecurityManager.EXIT_VALUE) {
+ throw new RuntimeException(utilityToStart
+ + " exit with an unexpected value "
+ + exit + ".");
+ }
+ System.err.format("Success: starting %s exited with status %d%n",
+ utilityToStart, TestSecurityManager.EXIT_VALUE);
+ }
} catch (Exception e) {
TestLibrary.bomb(e);
@@ -96,8 +100,7 @@
utilityToStart = utility;
try {
- int port = TestLibrary.getUnusedRandomPort();
- Thread thread = new Thread(new AltSecurityManager(port));
+ Thread thread = new Thread(new AltSecurityManager());
System.err.println("expecting RuntimeException for " +
"checkListen in child process");
long start = System.currentTimeMillis();
@@ -116,7 +119,7 @@
" terminated on time");
}
} finally {
- vm.destroy();
+ vm.cleanup();
vm = null;
}
}
--- a/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
/**/
public class TestSecurityManager extends SecurityManager {
+ public static final int EXIT_VALUE = 123;
+
public TestSecurityManager() {
}
@@ -36,7 +38,7 @@
// by the main test process to detect that the proper security
// manager has been installed in the relevant VMs.
//
- System.exit(1);
+ System.exit(EXIT_VALUE);
}
public void checkExit(int status) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/registry.security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,8 @@
+grant {
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+ permission java.util.PropertyPermission "env.class.path", "read";
+ permission java.io.FilePermission ".", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "setContextClassLoader";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/rmid.security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,7 @@
+grant {
+ permission java.lang.RuntimePermission "selectorProvider";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
+ permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.port", "read";
+ permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.timeout", "read";
+ permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Dummy
+ * @build TestLibrary Dummy RegistryVM RMIRegistryRunner
* @run main/othervm/policy=security.policy
* -Djava.rmi.server.useCodebaseOnly=false ClassPathCodebase
*/
@@ -48,8 +48,9 @@
public class ClassPathCodebase {
- /** wait 10 seconds for the registry process to be ready to call */
- private final static long REGISTRY_WAIT = 15000;
+ /** wait dozens of seconds for the registry process to be ready to call */
+ private static final long REGISTRY_WAIT =
+ (long)(10000 * TestLibrary.getTimeoutFactor());
private final static String dummyClassName = "Dummy";
@@ -64,7 +65,7 @@
TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
- Process rmiregistry = null;
+ RegistryVM rmiregistry = null;
try {
/*
@@ -82,27 +83,13 @@
* Spawn an rmiregistry in the "import" codebase directory.
*/
File rmiregistryDir =
- new File(System.getProperty("user.dir", "."), importCodebase);
-
- String rmiregistryCommand =
- System.getProperty("java.home") + File.separator +
- "bin" + File.separator + "rmiregistry";
-
- int port = TestLibrary.getUnusedRandomPort();
- String cmdarray[] = new String[] {
- rmiregistryCommand,
- "-J-Denv.class.path=.",
- "-J-Djava.rmi.server.codebase=" + exportCodebaseURL,
- Integer.toString(port) };
-
- System.err.println("\nCommand used to spawn rmiregistry process:");
- System.err.println("\t" + Arrays.asList(cmdarray).toString());
-
- rmiregistry = Runtime.getRuntime().exec(cmdarray, null, rmiregistryDir);
-
- // pipe rmiregistry output to our output, for debugging failures
- StreamPipe.plugTogether(rmiregistry.getInputStream(), System.err);
- StreamPipe.plugTogether(rmiregistry.getErrorStream(), System.err);
+ new File(System.getProperty("user.dir", "."), importCodebase);
+ rmiregistry = RegistryVM.createRegistryVMWithRunner("RMIRegistryRunner",
+ " -Denv.class.path=."
+ + " -Djava.rmi.server.codebase=" + exportCodebaseURL
+ + " -Duser.dir=" + rmiregistryDir.getAbsolutePath());
+ rmiregistry.start();
+ int port = rmiregistry.getPort();
/*
* Wait for the registry to initialize and be ready to call.
@@ -174,7 +161,7 @@
throw new RuntimeException("TEST FAILED: " + e.toString());
} finally {
if (rmiregistry != null) {
- rmiregistry.destroy();
+ rmiregistry.cleanup();
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/classPathCodebase/registry.security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,18 @@
+/*
+ * security policy used by the registry process started by RegistryVM.
+ */
+
+grant {
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+ permission java.util.PropertyPermission "env.class.path", "read";
+ permission java.io.FilePermission ".", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "setContextClassLoader";
+ permission java.io.FilePermission ".-Djava.rmi.server.codebase=file", "read";
+ permission java.io.FilePermission ".${/}-", "read";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+ permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/security.policy Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/registry/classPathCodebase/security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -18,6 +18,12 @@
// test needs to use java to exec an rmiregistry
permission java.io.FilePermission "${java.home}${/}bin${/}-", "execute";
- // test needs to communicate with this its registry
+ // test needs to communicate with its registry
permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+ permission java.util.PropertyPermission "java.security.policy", "read";
+ permission java.util.PropertyPermission "java.security.manager", "read";
+
+ // used by TestLibrary to determine extra commandline properties
+ permission java.io.FilePermission "..${/}..${/}test.props", "read";
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/readTest/CodebaseTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, 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 7102369 7094468 7100592
+ * @modules java.rmi/sun.rmi.registry
+ * java.rmi/sun.rmi.server
+ * java.rmi/sun.rmi.transport
+ * java.rmi/sun.rmi.transport.tcp
+ * @library ../../testlibrary
+ * @build TestLibrary RMIRegistryRunner RegistryVM JavaVM testPkg.* RegistryLookup
+ * @summary remove java.rmi.server.codebase property parsing from registyimpl
+ * @run main/othervm CodebaseTest
+*/
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+
+public class CodebaseTest {
+
+ public static void main(String args[]) throws Exception {
+ RegistryVM rmiregistry = null;
+ JavaVM client = null;
+ try {
+ File src = new File(System.getProperty("test.classes", "."), "testPkg");
+ File dest = new File(System.getProperty("user.dir", "."), "testPkg");
+ Files.move(src.toPath(), dest.toPath(),
+ StandardCopyOption.REPLACE_EXISTING);
+
+ File rmiregistryDir =
+ new File(System.getProperty("user.dir", "."), "rmi_tmp");
+ rmiregistryDir.mkdirs();
+ rmiregistry = RegistryVM.createRegistryVMWithRunner(
+ "RMIRegistryRunner",
+ " -Djava.rmi.server.useCodebaseOnly=false"
+ + " -Duser.dir=" + rmiregistryDir.getAbsolutePath());
+ rmiregistry.start();
+ int port = rmiregistry.getPort();
+
+ File srcReadTest = new File(System.getProperty("test.classes", "."),
+ "RegistryLookup.class");
+ File destReadTest = new File(System.getProperty("user.dir", "."),
+ "RegistryLookup.class");
+ Files.move(srcReadTest.toPath(), destReadTest.toPath(),
+ StandardCopyOption.REPLACE_EXISTING);
+
+ File codebase = new File(System.getProperty("user.dir", "."));
+ client = new JavaVM("RegistryLookup",
+ " -Djava.rmi.server.codebase=" + codebase.toURI().toURL()
+ + " -cp ." + File.pathSeparator + System.getProperty("test.class.path"),
+ Integer.toString(port));
+ int exit = client.execute();
+ if (exit == RegistryLookup.EXIT_FAIL) {
+ throw new RuntimeException("Test Fails");
+ }
+ } finally {
+ if (rmiregistry != null) {
+ rmiregistry.cleanup();
+ }
+ if (client != null) {
+ client.cleanup();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/readTest/RegistryLookup.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, 2017, 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.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+
+public class RegistryLookup {
+ public static final int EXIT_FAIL = 1;
+
+ public static void main(String args[]) throws Exception {
+ Registry registry = null;
+ int exit = 0;
+ try {
+ int port = Integer.valueOf(args[0]);
+
+ testPkg.Server obj = new testPkg.Server();
+ testPkg.Hello stub =
+ (testPkg.Hello) UnicastRemoteObject.exportObject(obj, 0);
+ // Bind the remote object's stub in the registry
+ registry = LocateRegistry.getRegistry(port);
+ registry.bind("Hello", stub);
+ System.err.println("Server ready");
+
+ testPkg.Client client = new testPkg.Client(port);
+ String testStubReturn = client.testStub();
+ if(!testStubReturn.equals(obj.hello)) {
+ throw new RuntimeException("Test Fails : "
+ + "unexpected string from stub call");
+ }
+ registry.unbind("Hello");
+ System.out.println("Test passed");
+ } catch (Exception ex) {
+ exit = EXIT_FAIL;
+ ex.printStackTrace();
+ }
+ // need to exit explicitly, and parent process uses exit value
+ // to tell if the test passed.
+ System.exit(exit);
+ }
+}
--- a/jdk/test/java/rmi/registry/readTest/readTest.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class readTest {
-
- public static void main(String args[]) throws Exception {
- try {
- testPkg.Server obj = new testPkg.Server();
- testPkg.Hello stub = (testPkg.Hello) UnicastRemoteObject.exportObject(obj, 0);
- // Bind the remote object's stub in the registry
- Registry registry =
- LocateRegistry.getRegistry(TestLibrary.READTEST_REGISTRY_PORT);
- registry.bind("Hello", stub);
-
- System.err.println("Server ready");
-
- // now, let's test client
- testPkg.Client client =
- new testPkg.Client(TestLibrary.READTEST_REGISTRY_PORT);
- String testStubReturn = client.testStub();
- if(!testStubReturn.equals(obj.hello)) {
- throw new RuntimeException("Test Fails : unexpected string from stub call");
- } else {
- System.out.println("Test passed");
- }
- registry.unbind("Hello");
-
- } catch (Exception e) {
- System.err.println("Server exception: " + e.toString());
- e.printStackTrace();
- }
-
- }
-}
--- a/jdk/test/java/rmi/registry/readTest/readTest.sh Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 7102369 7094468 7100592
-# @modules java.rmi/sun.rmi.registry
-# java.rmi/sun.rmi.server
-# java.rmi/sun.rmi.transport
-# java.rmi/sun.rmi.transport.tcp
-# @library ../../testlibrary
-# @build TestLibrary
-# @summary remove java.rmi.server.codebase property parsing from registyimpl
-# @run shell readTest.sh
-# @key intermittent
-
-OS=`uname -s`
-VER=`uname -r`
-ARGS=""
-REGARGS=""
-
-case "$OS" in
- SunOS | Linux | Darwin | AIX )
- PS=":"
- FS="/"
- CHMOD="${FS}bin${FS}chmod"
- FILEURL="file:"
- ;;
- Windows* )
- PS=";"
- FS="\\"
- CHMOD="chmod"
- FILEURL="file:/"
- if [ "$VER" -eq "5" ]; then
- ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000"
- REGARGS="-J-Djdk.net.ephemeralPortRange.low=1024 -J-Djdk.net.ephemeralPortRange.high=65000"
- fi
- ;;
- CYGWIN* )
- PS=";"
- FS="/"
- CHMOD="chmod"
- FILEURL="file:/"
- if [ "$VER" -eq "5" ]; then
- ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000"
- REGARGS="-J-Djdk.net.ephemeralPortRange.low=1024 -J-Djdk.net.ephemeralPortRange.high=65000"
- fi
- ;;
- * )
- echo "Unrecognized system!"
- exit 1;
- ;;
-esac
-
-TEST_CLASSPATH=.$PS${TESTCLASSPATH:-$TESTCLASSES}
-cp -r ${TESTSRC}${FS}* .
-${CHMOD} -R u+w *
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} testPkg${FS}*java
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -cp $TEST_CLASSPATH readTest.java
-
-mkdir rmi_tmp
-RMIREG_OUT=rmi.out
-#start rmiregistry without any local classes on classpath
-cd rmi_tmp
-# NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT
-${TESTJAVA}${FS}bin${FS}rmiregistry ${REGARGS} -J-Djava.rmi.server.useCodebaseOnly=false \
- ${TESTTOOLVMOPTS} 60005 > ..${FS}${RMIREG_OUT} 2>&1 &
-RMIREG_PID=$!
-# allow some time to start
-sleep 3
-cd ..
-
-case "$OS" in
- CYGWIN* )
- CODEBASE=`cygpath -w $PWD`
- ;;
- * )
- CODEBASE=`pwd`
- ;;
-esac
-# trailing / after code base is important for rmi codebase property.
-TESTVMOPTS="${TESTVMOPTS} \
- --add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED \
- --add-exports java.rmi/sun.rmi.server=ALL-UNNAMED \
- --add-exports java.rmi/sun.rmi.transport=ALL-UNNAMED \
- --add-exports java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp $TEST_CLASSPATH ${ARGS} -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 &
-TEST_PID=$!
-#bulk of testcase - let it run for a while
-sleep 5
-
-#we're done, kill processes first
-kill -9 ${RMIREG_PID} ${TEST_PID}
-sleep 3
-
-echo "Test output : "
-
-cat OUT.TXT
-echo "=============="
-echo "rmiregistry output : "
-cat ${RMIREG_OUT}
-echo "=============="
-
-grep "Server ready" OUT.TXT
-result1=$?
-grep "Test passed" OUT.TXT
-result2=$?
-
-if [ $result1 -eq 0 -a $result2 -eq 0 ]
-then
- echo "Passed"
- exitCode=0;
-else
- echo "Failed"
- exitCode=1
-fi
-rm -rf OUT.TXT ${RMIREG_OUT} rmi_tmp
-exit ${exitCode}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/readTest/registry.security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,12 @@
+grant {
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+ permission java.util.PropertyPermission "env.class.path", "read";
+ permission java.io.FilePermission ".", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.lang.RuntimePermission "setContextClassLoader";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+ permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/reexport/Reexport.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/registry/reexport/Reexport.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -29,7 +29,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
* @run main/othervm Reexport
*/
@@ -114,7 +114,7 @@
public static void makeRegistry() {
try {
- subreg = REGISTRY.createREGISTRY();
+ subreg = RegistryVM.createRegistryVM();
subreg.start();
port = subreg.getPort();
System.out.println("Starting registry on port " + port);
@@ -125,12 +125,12 @@
}
}
- private static REGISTRY subreg = null;
+ private static RegistryVM subreg = null;
private static int port = -1;
public static void killRegistry() {
if (subreg != null) {
- subreg.shutdown();
+ subreg.cleanup();
subreg = null;
}
}
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -230,6 +230,22 @@
}
/**
+ * Return exit value for vm process.
+ * @return exit value for vm process
+ * @throws IllegalThreadStateException if the vm process has not yet terminated
+ */
+ public int exitValue() {
+ return vm.exitValue();
+ }
+
+ /**
+ * Destroy the vm process, and do necessary cleanup.
+ */
+ public void cleanup() {
+ destroy();
+ }
+
+ /**
* Destroys the VM, waits for it to terminate, and returns
* its exit status.
*
--- a/jdk/test/java/rmi/testlibrary/REGISTRY.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * 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.io.OutputStream;
-import java.io.IOException;
-
-/**
- * Class to run and control rmiregistry in a sub-process.
- *
- * We can't kill a registry if we have too-close control
- * over it. We must make it in a subprocess, and then kill the
- * subprocess when it has served our needs.
- */
-public class REGISTRY extends JavaVM {
-
- private static final double START_TIMEOUT =
- 20_000 * TestLibrary.getTimeoutFactor();
- private static final String DEFAULT_RUNNER = "RegistryRunner";
-
- private int port = -1;
-
- private REGISTRY(String runner, OutputStream out, OutputStream err,
- String options, int port) {
- super(runner, options, Integer.toString(port), out, err);
- try {
- Class runnerClass = Class.forName(runner);
- if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
- throw new RuntimeException("runner class must be RegistryRunner"
- + " or its sub class");
- }
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(ex);
- }
- this.port = port;
- }
-
- public static REGISTRY createREGISTRY() {
- return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
- }
-
- public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
- String options, int port) {
- return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
- }
-
- public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
- return createREGISTRYWithRunner(runner, System.out, System.err, options, 0);
- }
-
- public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
- OutputStream err, String options, int port) {
- options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
- + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
- REGISTRY reg = new REGISTRY(runner, out, err, options, port);
- return reg;
- }
-
- /**
- * Starts the registry in a sub-process and waits up to
- * the given timeout period to confirm that it's running,
- * and get the port where it's running.
- */
- public void start() throws IOException {
- super.start();
- long startTime = System.currentTimeMillis();
- long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
- while (true) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ignore) { }
-
- String output = outputStream.ba.toString();
- port = RegistryRunner.getRegistryPort(output);
- if (port != -1) {
- break;
- }
- if (System.currentTimeMillis() > deadline) {
- TestLibrary.bomb("Failed to start registry, giving up after " +
- (System.currentTimeMillis() - startTime) + "ms.", null);
- }
- }
- }
-
- /**
- * Shuts down the registry.
- */
- public void shutdown() {
- RegistryRunner.requestExit(port);
- }
-
- /**
- * Gets the port where the registry is serving.
- */
- public int getPort() {
- return port;
- }
-}
--- a/jdk/test/java/rmi/testlibrary/RMID.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/testlibrary/RMID.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -140,18 +140,6 @@
}
private static String makeArgs(boolean includePortArg, int port) {
- String propagateManager = null;
-
- // rmid will run with a security manager set, but no policy
- // file - it should not need one.
- if (System.getSecurityManager() == null) {
- propagateManager = MANAGER_OPTION +
- TestParams.defaultSecurityManager;
- } else {
- propagateManager = MANAGER_OPTION +
- System.getSecurityManager().getClass().getName();
- }
-
// getAbsolutePath requires permission to read user.dir
String args =
" -log " + (new File(LOGDIR, log)).getAbsolutePath();
@@ -210,7 +198,30 @@
boolean debugExec, boolean includePortArg,
int port)
{
+ return createRMIDWithOptions(out, err, debugExec, includePortArg, port, "");
+ }
+
+ /**
+ * Create a RMID on a specified port capturing stdout and stderr
+ * with additional command line options and whether to print out
+ * debugging information that is used for spawning activation groups.
+ *
+ * @param out the OutputStream where the normal output of the
+ * rmid subprocess goes
+ * @param err the OutputStream where the error output of the
+ * rmid subprocess goes
+ * @param debugExec whether to print out debugging information
+ * @param includePortArg whether to include port argument
+ * @param port the port on which rmid accepts requests
+ * @param additionalOptions additional command line options
+ * @return a RMID instance
+ */
+ public static RMID createRMIDWithOptions(OutputStream out, OutputStream err,
+ boolean debugExec, boolean includePortArg,
+ int port, String additionalOptions)
+ {
String options = makeOptions(port, debugExec, false);
+ options += " " + additionalOptions;
String args = makeArgs(includePortArg, port);
RMID rmid = new RMID("sun.rmi.server.Activation", options, args,
out, err, port);
@@ -223,6 +234,19 @@
return createRMID(System.out, System.err, true, false, 0);
}
+ /**
+ * Create a RMID on an ephemeral port capturing stdout and stderr
+ * with additional command line options.
+ *
+ * @param additionalOptions additional command line options
+ * @return a RMID instance
+ */
+ public static RMID createRMIDOnEphemeralPortWithOptions(
+ String additionalOptions) {
+ return createRMIDWithOptions(System.out, System.err,
+ true, false, 0, additionalOptions);
+ }
+
public static RMID createRMIDOnEphemeralPort(OutputStream out,
OutputStream err,
boolean debugExec)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RMIRegistryRunner.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, 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.rmi.*;
+import java.rmi.registry.*;
+import java.rmi.server.*;
+
+/**
+ * Class to run a rmiregistry whose VM can be told to exit remotely;
+ * Difference between this class and RegistryRunner is that this class
+ * simulate rmiregistry closer than RegistryRunner.
+ */
+public class RMIRegistryRunner extends RegistryRunner
+{
+ public RMIRegistryRunner() throws RemoteException {
+ }
+
+ /**
+ * port 0 means to use ephemeral port to start registry.
+ *
+ * @param args command line arguments passed in from main
+ * @return the port number on which registry accepts requests
+ */
+ protected static int init(String[] args) {
+ try {
+ if (args.length == 0) {
+ System.err.println("Usage: <port>");
+ System.exit(0);
+ }
+ int port = -1;
+ port = Integer.parseInt(args[0]);
+
+ // call RegistryImpl.createRegistry to simulate rmiregistry.
+ registry = sun.rmi.registry.RegistryImpl.createRegistry(port);
+ if (port == 0) {
+ port = TestLibrary.getRegistryPort(registry);
+ }
+
+ // create a remote object to tell this VM to exit
+ exiter = new RMIRegistryRunner();
+ Naming.rebind("rmi://localhost:" + port +
+ "/RemoteExiter", exiter);
+
+ return port;
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ int port = init(args);
+ notify(port);
+ }
+}
--- a/jdk/test/java/rmi/testlibrary/RegistryRunner.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/testlibrary/RegistryRunner.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -29,7 +29,7 @@
/**
* Class to run a registry whose VM can be told to exit remotely; using
- * the rmiregistry in this fashion makes tests more robust under
+ * a registry (in a sub-process) in this fashion makes tests more robust under
* windows where Process.destroy() seems not to be 100% reliable.
*/
public class RegistryRunner extends UnicastRemoteObject
@@ -38,8 +38,8 @@
private static final String PORT_LABEL_START = "RegistryRunner.port.start:";
private static final String PORT_LABEL_END = ":RegistryRunner.port.end";
- private static Registry registry = null;
- private static RemoteExiter exiter = null;
+ protected static Registry registry = null;
+ protected static RemoteExiter exiter = null;
public RegistryRunner() throws RemoteException {
}
@@ -72,6 +72,7 @@
} catch (RemoteException re) {
}
e = null;
+
} catch (java.net.MalformedURLException mfue) {
// will not happen
} catch (NotBoundException nbe) {
@@ -97,6 +98,9 @@
/**
* port 0 means to use ephemeral port to start registry.
+ *
+ * @param args command line arguments passed in from main
+ * @return the port number on which registry accepts requests
*/
protected static int init(String[] args) {
try {
@@ -128,13 +132,15 @@
}
/**
- * REGISTRY.start() will filter the output of registry subprocess,
- * when valid port is detected, REGISTRY.start() returns.
+ * RegistryVM.start() will filter the output of registry subprocess,
+ * when valid port is detected, RegistryVM.start() returns.
* So, for subclass, it's important to call this method after registry
* is initialized and necessary remote objects have been bound.
+ *
+ * @param port the port on which registry accepts requests
*/
protected static void notify(int port) {
- // this output is important for REGISTRY to get the port
+ // this output is important for RegistryVM to get the port
// where rmiregistry is serving
System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
System.out.flush();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RegistryVM.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Class to run and control registry/rmiregistry in a sub-process.
+ * The behaviour changes when use different runner, currently
+ * there are 2 built-in runners, RegistryRunner and RMIRegistryRunner.
+ *
+ * We can't kill a registry if we have too-close control
+ * over it. We must make it in a subprocess, and then kill the
+ * subprocess when it has served our needs.
+ */
+public class RegistryVM extends JavaVM {
+
+ private static final double START_TIMEOUT =
+ 20_000 * TestLibrary.getTimeoutFactor();
+ private static final String DEFAULT_RUNNER = "RegistryRunner";
+
+ private int port = -1;
+
+ private RegistryVM(String runner, OutputStream out, OutputStream err,
+ String options, int port) {
+ super(runner, options, Integer.toString(port), out, err);
+ try {
+ Class runnerClass = Class.forName(runner);
+ if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
+ throw new RuntimeException("runner class must be RegistryRunner"
+ + " or its sub class");
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException(ex);
+ }
+ this.port = port;
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port.
+ *
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM() {
+ return createRegistryVMWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port with additional
+ * command line options.
+ *
+ * @param options command line options
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM(String options) {
+ return createRegistryVMWithRunner(
+ DEFAULT_RUNNER, System.out, System.err, options, 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on a specified port capturing stdout and
+ * stderr with additional command line options.
+ *
+ * @param out the OutputStream where the normal output of the
+ * registry subprocess goes
+ * @param err the OutputStream where the error output of the
+ * registry subprocess goes
+ * @param options the command line options
+ * @param port the port on which Registry accepts requests
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVM(OutputStream out, OutputStream err,
+ String options, int port) {
+ return createRegistryVMWithRunner(DEFAULT_RUNNER, out, err, options, port);
+ }
+
+ /**
+ * Create a RegistryVM instance on an ephemeral port with additional
+ * command line options and a specified runner.
+ *
+ * @param runner the runner class name
+ * @param options command line options
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVMWithRunner(String runner, String options) {
+ return createRegistryVMWithRunner(runner, System.out, System.err, options, 0);
+ }
+
+ /**
+ * Create a RegistryVM instance on a specified port capturing stdout and
+ * stderr with additional command line options and a specified runner.
+ *
+ * @param runner the runner class name
+ * @param out the OutputStream where the normal output of the
+ * registry subprocess goes
+ * @param err the OutputStream where the error output of the
+ * registry subprocess goes
+ * @param options the command line options
+ * @param port the port on which Registry accepts requests
+ * @return a RegistryVM instance
+ */
+ public static RegistryVM createRegistryVMWithRunner(String runner, OutputStream out,
+ OutputStream err, String options, int port) {
+ options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
+ + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
+ RegistryVM reg = new RegistryVM(runner, out, err, options, port);
+ reg.setPolicyFile(TestParams.defaultRegistryPolicy);
+ return reg;
+ }
+
+ /**
+ * Starts the registry in a sub-process and waits up to
+ * the given timeout period to confirm that it's running,
+ * and get the port where it's running.
+ *
+ * @throws IOException if fails to start subprocess
+ */
+ public void start() throws IOException {
+ super.start();
+ long startTime = System.currentTimeMillis();
+ long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignore) { }
+
+ String output = outputStream.ba.toString();
+ port = RegistryRunner.getRegistryPort(output);
+ if (port != -1) {
+ break;
+ }
+ try {
+ int exit = vm.exitValue();
+ TestLibrary.bomb("[RegistryVM] registry sub-process exited with status "
+ + exit + ".");
+ } catch (IllegalThreadStateException ignore) { }
+
+ if (System.currentTimeMillis() > deadline) {
+ TestLibrary.bomb("Failed to start registry, giving up after " +
+ (System.currentTimeMillis() - startTime) + "ms.", null);
+ }
+ }
+ }
+
+ /**
+ * Shuts down the registry.
+ */
+ @Override
+ public void cleanup() {
+ RegistryRunner.requestExit(port);
+ super.destroy();
+ }
+
+ /**
+ * Gets the port where the registry is serving.
+ *
+ * @return the port where the registry is serving
+ */
+ public int getPort() {
+ return port;
+ }
+}
--- a/jdk/test/java/rmi/testlibrary/TestParams.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/testlibrary/TestParams.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -42,6 +42,9 @@
/** name of default security policy for RMID */
public static final String defaultRmidPolicy;
+ /** name of default security policy for RegistryVM */
+ public static final String defaultRegistryPolicy;
+
/** name of default security policy for activation groups */
public static final String defaultGroupPolicy;
@@ -69,6 +72,9 @@
defaultRmidPolicy =
testSrc + File.separatorChar + "rmid.security.policy";
+ defaultRegistryPolicy =
+ testSrc + File.separatorChar + "registry.security.policy";
+
defaultGroupPolicy =
testSrc + File.separatorChar + "group.security.policy";
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -33,7 +33,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Test TestImpl REGISTRY RegistryRunner
+ * @build TestLibrary Test TestImpl RegistryVM RegistryRunner
* @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
*/
@@ -68,21 +68,18 @@
static public void main(String[] args) {
- REGISTRY testImplVM = null;
+ RegistryVM testImplVM = null;
System.err.println("\nregression test for 4118056\n");
TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
try {
- String options = " -Djava.security.policy=" +
- TestParams.defaultPolicy +
- " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
+ String options = " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
" -Djava.rmi.dgc.leaseValue=500000" +
" -Dsun.rmi.dgc.checkInterval=" +
- (HOLD_TARGET_TIME - 5000) +
- "" ;
+ (HOLD_TARGET_TIME - 5000);
- testImplVM = REGISTRY.createREGISTRYWithRunner("TestImpl", options);
+ testImplVM = RegistryVM.createRegistryVMWithRunner("TestImpl", options);
testImplVM.start();
registryPort = testImplVM.getPort();
@@ -107,7 +104,7 @@
TestLibrary.bomb("test failed in main()", e);
} finally {
if (testImplVM != null) {
- testImplVM.shutdown();
+ testImplVM.cleanup();
testImplVM = null;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/registry.security.policy Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * security policy used by the registry sub-process
+ */
+
+grant {
+ // used by TestLibrary to determine extra commandline properties
+ permission java.io.FilePermission "..${/}..${/}test.props", "read";
+
+ // property specifically accessed by this test.
+ permission java.util.PropertyPermission "sun.rmi.transport.cleanInterval", "write";
+ permission java.util.PropertyPermission "package.restrict.access.sun", "read";
+ permission java.util.PropertyPermission "package.restrict.access.sun.rmi", "read";
+
+ // test needs to use java to exec an EchoImpl object
+ permission java.io.FilePermission "${java.home}${/}bin${/}java", "execute";
+
+ // used by TestLibrary to determine test environment
+ permission java.util.PropertyPermission "test.*", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+
+ permission java.util.PropertyPermission "java.security.policy", "read";
+ permission java.util.PropertyPermission "java.security.manager", "read";
+
+ // test needs to export rmid and communicate with objects on arbitrary ports
+ permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+};
--- a/jdk/test/java/time/TEST.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/TEST.properties Tue Jan 24 00:30:23 2017 +0100
@@ -1,7 +1,6 @@
# Threeten test uses TestNG
TestNG.dirs = .
othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
-modules = jdk.localedata
lib.dirs = ../../lib/testlibrary
lib.build = jdk.testlibrary.RandomFactory
modules = java.base/java.time:open java.base/java.time.chrono:open java.base/java.time.zone:open
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java Tue Jan 24 00:30:23 2017 +0100
@@ -880,25 +880,6 @@
}
//-----------------------------------------------------------------------
- @DataProvider(name="patternPrint")
- Object[][] data_patternPrint() {
- return new Object[][] {
- {"Q", date(2012, 2, 10), "1"},
- {"QQ", date(2012, 2, 10), "01"},
- {"QQQ", date(2012, 2, 10), "Q1"},
- {"QQQQ", date(2012, 2, 10), "1st quarter"},
- {"QQQQQ", date(2012, 2, 10), "1"},
- };
- }
-
- @Test(dataProvider="patternPrint")
- public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
- DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
- String test = f.format(temporal);
- assertEquals(test, expected);
- }
-
- //-----------------------------------------------------------------------
@DataProvider(name="localePatterns")
Object[][] localizedDateTimePatterns() {
return new Object[][] {
@@ -914,48 +895,6 @@
{null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a z"},
{null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a"},
{null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.US, "h:mm a"},
-
- // French Locale and ISO Chronology
- {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
- {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
- {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
- {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
- {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
- {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
- {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
- {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
- {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
- {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
-
- // Japanese Locale and JapaneseChronology
- {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
- {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
- {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
- {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
- {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
- {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
- {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
- {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
-
- // Chinese Local and Chronology
- {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
- {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
- {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
- {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
- {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
- {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
- {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
- {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
- {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
- {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
- {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
};
}
@@ -1004,5 +943,4 @@
private static Temporal date(int y, int m, int d) {
return LocalDate.of(y, m, d);
}
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * 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:
+ *
+ * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * 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 JSR-310 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.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+package test.java.time.format;
+
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.time.LocalDate;
+import java.time.temporal.Temporal;
+
+import java.util.Locale;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.
+ */
+@Test
+public class TestDateTimeFormatterBuilderWithLocale {
+
+ private DateTimeFormatterBuilder builder;
+
+ @BeforeMethod
+ public void setUp() {
+ builder = new DateTimeFormatterBuilder();
+ }
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="patternPrint")
+ Object[][] data_patternPrint() {
+ return new Object[][] {
+ {"Q", date(2012, 2, 10), "1"},
+ {"QQ", date(2012, 2, 10), "01"},
+ {"QQQ", date(2012, 2, 10), "Q1"},
+ {"QQQQ", date(2012, 2, 10), "1st quarter"},
+ {"QQQQQ", date(2012, 2, 10), "1"},
+ };
+ }
+
+ @Test(dataProvider="patternPrint")
+ public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
+ DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
+ String test = f.format(temporal);
+ assertEquals(test, expected);
+ }
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="localePatterns")
+ Object[][] localizedDateTimePatterns() {
+ return new Object[][] {
+ // French Locale and ISO Chronology
+ {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
+ {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
+ {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
+ {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
+ {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
+ {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
+ {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
+ {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
+ {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
+ {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
+
+ // Japanese Locale and JapaneseChronology
+ {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
+ {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
+ {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+ {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
+ {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
+ {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
+ {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
+ {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
+
+ // Chinese Local and Chronology
+ {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
+ {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
+ {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
+ {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+ {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+ {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+ {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+ {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
+ {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
+ {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
+ {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+ };
+ }
+
+ @Test(dataProvider="localePatterns")
+ public void test_getLocalizedDateTimePattern(FormatStyle dateStyle, FormatStyle timeStyle,
+ Chronology chrono, Locale locale, String expected) {
+ String actual = DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale);
+ assertEquals(actual, expected, "Pattern " + convertNonAscii(actual));
+ }
+
+ /**
+ * Returns a string that includes non-ascii characters after expanding
+ * the non-ascii characters to their Java language \\uxxxx form.
+ * @param input an input string
+ * @return the encoded string.
+ */
+ private String convertNonAscii(String input) {
+ StringBuilder sb = new StringBuilder(input.length() * 6);
+ for (int i = 0; i < input.length(); i++) {
+ char ch = input.charAt(i);
+ if (ch < 255) {
+ sb.append(ch);
+ } else {
+ sb.append("\\u");
+ sb.append(Integer.toHexString(ch));
+ }
+ }
+ return sb.toString();
+ }
+
+ private static Temporal date(int y, int m, int d) {
+ return LocalDate.of(y, m, d);
+ }
+}
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -80,7 +80,6 @@
public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
Locale enUS = new Locale("en", "US");
- Locale ptBR = new Locale("pt", "BR");
//-----------------------------------------------------------------------
@DataProvider(name = "Text")
@@ -94,14 +93,6 @@
{DAY_OF_WEEK, 6, TextStyle.SHORT, enUS, "Sat"},
{DAY_OF_WEEK, 7, TextStyle.SHORT, enUS, "Sun"},
- {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
- {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
- {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
- {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
- {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
- {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
- {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
-
{DAY_OF_WEEK, 1, TextStyle.FULL, enUS, "Monday"},
{DAY_OF_WEEK, 2, TextStyle.FULL, enUS, "Tuesday"},
{DAY_OF_WEEK, 3, TextStyle.FULL, enUS, "Wednesday"},
@@ -110,14 +101,6 @@
{DAY_OF_WEEK, 6, TextStyle.FULL, enUS, "Saturday"},
{DAY_OF_WEEK, 7, TextStyle.FULL, enUS, "Sunday"},
- {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
- {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
- {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
- {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
- {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
- {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
- {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
-
{MONTH_OF_YEAR, 1, TextStyle.SHORT, enUS, "Jan"},
{MONTH_OF_YEAR, 2, TextStyle.SHORT, enUS, "Feb"},
{MONTH_OF_YEAR, 3, TextStyle.SHORT, enUS, "Mar"},
@@ -131,19 +114,6 @@
{MONTH_OF_YEAR, 11, TextStyle.SHORT, enUS, "Nov"},
{MONTH_OF_YEAR, 12, TextStyle.SHORT, enUS, "Dec"},
- {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
- {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
- {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
- {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
- {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
- {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
- {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
- {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
- {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
- {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
- {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
- {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
-
{MONTH_OF_YEAR, 1, TextStyle.FULL, enUS, "January"},
{MONTH_OF_YEAR, 2, TextStyle.FULL, enUS, "February"},
{MONTH_OF_YEAR, 3, TextStyle.FULL, enUS, "March"},
@@ -157,19 +127,6 @@
{MONTH_OF_YEAR, 11, TextStyle.FULL, enUS, "November"},
{MONTH_OF_YEAR, 12, TextStyle.FULL, enUS, "December"},
- {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
- {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
- {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
- {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
- {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
- {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
- {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
- {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
- {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
- {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
- {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
- {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
-
{AMPM_OF_DAY, 0, TextStyle.SHORT, enUS, "AM"},
{AMPM_OF_DAY, 1, TextStyle.SHORT, enUS, "PM"},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * 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:
+ *
+ * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * 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 JSR-310 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.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.AMPM_OF_DAY;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test SimpleDateTimeTextProviderWithLocale.
+ */
+@Test
+public class TestDateTimeTextProviderWithLocale extends AbstractTestPrinterParser {
+
+ Locale enUS = new Locale("en", "US");
+ Locale ptBR = new Locale("pt", "BR");
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name = "Text")
+ Object[][] data_text() {
+ return new Object[][] {
+ {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
+ {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
+ {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
+ {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
+ {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
+ {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
+ {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
+
+ {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
+ {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
+ {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
+ {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
+ {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
+ {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
+ {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
+
+ {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
+ {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
+ {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
+ {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
+ {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
+ {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
+ {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
+ {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
+ {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
+ {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
+ {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
+ {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
+
+ {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
+ {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
+ {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
+ {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
+ {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
+ {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
+ {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
+ {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
+ {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
+ {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
+ {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
+ {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
+
+ };
+ }
+
+ @Test(dataProvider = "Text")
+ public void test_getText(TemporalField field, Number value, TextStyle style, Locale locale, String expected) {
+ DateTimeFormatter fmt = getFormatter(field, style).withLocale(locale);
+ assertEquals(fmt.format(ZonedDateTime.now().with(field, value.longValue())), expected);
+ }
+
+}
--- a/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Tue Jan 24 00:30:23 2017 +0100
@@ -20,13 +20,14 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package test.java.time.format;
-
/*
* @test
+ * @modules jdk.localedata
* @bug 8146750
* @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
*/
+package test.java.time.format;
+
import static org.testng.Assert.assertEquals;
import java.time.DayOfWeek;
--- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java Tue Jan 24 00:30:23 2017 +0100
@@ -20,6 +20,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/*
+ *
+ * @test
+ * @modules jdk.localedata
+ */
+
package test.java.time.format;
import static org.testng.Assert.assertEquals;
--- a/jdk/test/java/time/test/java/time/format/TestTextParser.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -68,16 +68,9 @@
import java.text.ParsePosition;
import java.time.DayOfWeek;
-import java.time.chrono.ChronoLocalDate;
-import java.time.chrono.JapaneseChronology;
-import java.time.chrono.HijrahDate;
-import java.time.chrono.JapaneseDate;
-import java.time.chrono.MinguoDate;
-import java.time.chrono.ThaiBuddhistDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
-import java.time.format.SignStyle;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQueries;
@@ -92,8 +85,6 @@
*/
@Test
public class TestTextParser extends AbstractTestPrinterParser {
- static final Locale RUSSIAN = new Locale("ru");
- static final Locale FINNISH = new Locale("fi");
//-----------------------------------------------------------------------
@DataProvider(name="error")
@@ -213,20 +204,6 @@
};
}
- // Test data is dependent on localized resources.
- @DataProvider(name="parseStandaloneText")
- Object[][] providerStandaloneText() {
- // Locale, TemporalField, TextStyle, expected value, input text
- return new Object[][] {
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 1, "\u044f\u043d\u0432."},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
- {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, 2, "tiistai"},
- {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, 2, "ti"},
- };
- }
-
@DataProvider(name="parseDayOfWeekText")
Object[][] providerDayOfWeekData() {
return new Object[][] {
@@ -234,26 +211,9 @@
{Locale.US, "e", "1", DayOfWeek.SUNDAY},
{Locale.US, "ee", "01", DayOfWeek.SUNDAY},
{Locale.US, "c", "1", DayOfWeek.SUNDAY},
-
- {Locale.UK, "e", "1", DayOfWeek.MONDAY},
- {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
- {Locale.UK, "c", "1", DayOfWeek.MONDAY},
};
}
- // Test data is dependent on localized resources.
- @DataProvider(name="parseLenientText")
- Object[][] providerLenientText() {
- // Locale, TemporalField, expected value, input text
- return new Object[][] {
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
- {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
- };
- }
-
-
@Test(dataProvider="parseText")
public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception {
@@ -269,14 +229,6 @@
assertEquals(pos.getIndex(), input.length());
}
- @Test(dataProvider="parseStandaloneText")
- public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
- DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
- ParsePosition pos = new ParsePosition(0);
- assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
- assertEquals(pos.getIndex(), input.length());
- }
-
@Test(dataProvider="parseDayOfWeekText")
public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
@@ -374,25 +326,6 @@
}
//-----------------------------------------------------------------------
- public void test_parse_french_short_strict_full_noMatch() throws Exception {
- setStrict(true);
- ParsePosition pos = new ParsePosition(0);
- getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
- .parseUnresolved("janvier", pos);
- assertEquals(pos.getErrorIndex(), 0);
- }
-
- public void test_parse_french_short_strict_short_match() throws Exception {
- setStrict(true);
- ParsePosition pos = new ParsePosition(0);
- assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
- .parseUnresolved("janv.", pos)
- .getLong(MONTH_OF_YEAR),
- 1L);
- assertEquals(pos.getIndex(), 5);
- }
-
- //-----------------------------------------------------------------------
public void test_parse_full_lenient_full_match() throws Exception {
setStrict(false);
ParsePosition pos = new ParsePosition(0);
@@ -436,51 +369,4 @@
assertEquals(pos.getIndex(), 1);
}
- @Test(dataProvider="parseLenientText")
- public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
- setStrict(false);
- ParsePosition pos = new ParsePosition(0);
- DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
- assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
- assertEquals(pos.getIndex(), input.length());
- }
-
- //-----------------------------------------------------------------------
- @DataProvider(name="parseChronoLocalDate")
- Object[][] provider_chronoLocalDate() {
- return new Object[][] {
- { HijrahDate.now() },
- { JapaneseDate.now() },
- { MinguoDate.now() },
- { ThaiBuddhistDate.now() }};
- }
-
- private static final DateTimeFormatter fmt_chrono =
- new DateTimeFormatterBuilder()
- .optionalStart()
- .appendChronologyId()
- .appendLiteral(' ')
- .optionalEnd()
- .optionalStart()
- .appendText(ChronoField.ERA, TextStyle.SHORT)
- .appendLiteral(' ')
- .optionalEnd()
- .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
- .appendLiteral('-')
- .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
- .appendLiteral('-')
- .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
- .toFormatter();
-
- @Test(dataProvider="parseChronoLocalDate")
- public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
- System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
- assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
-
- DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
- .withChronology(date.getChronology());
- System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
- assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
- }
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextParserWithLocale.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * 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:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * 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 JSR-310 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.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import java.text.ParsePosition;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.DayOfWeek;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.TextStyle;
+import java.time.format.SignStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test TextPrinterParser.
+ */
+@Test
+public class TestTextParserWithLocale extends AbstractTestPrinterParser {
+ static final Locale RUSSIAN = new Locale("ru");
+ static final Locale FINNISH = new Locale("fi");
+
+ @DataProvider(name="parseDayOfWeekText")
+ Object[][] providerDayOfWeekData() {
+ return new Object[][] {
+ // Locale, pattern, input text, expected DayOfWeek
+ {Locale.US, "e", "1", DayOfWeek.SUNDAY},
+ {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+ {Locale.US, "c", "1", DayOfWeek.SUNDAY},
+
+ {Locale.UK, "e", "1", DayOfWeek.MONDAY},
+ {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+ {Locale.UK, "c", "1", DayOfWeek.MONDAY},
+ };
+ }
+
+ @Test(dataProvider="parseDayOfWeekText")
+ public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
+ DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(DayOfWeek.from(formatter.parse(input, pos)), expected);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+ //--------------------------------------------------------------------
+ // Test data is dependent on localized resources.
+ @DataProvider(name="parseStandaloneText")
+ Object[][] providerStandaloneText() {
+ // Locale, TemporalField, TextStyle, expected value, input text
+ return new Object[][] {
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, 12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 1, "\u044f\u043d\u0432."},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
+ {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, 2, "tiistai"},
+ {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, 2, "ti"},
+ };
+ }
+
+ // Test data is dependent on localized resources.
+ @DataProvider(name="parseLenientText")
+ Object[][] providerLenientText() {
+ // Locale, TemporalField, expected value, input text
+ return new Object[][] {
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
+ {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
+ };
+ }
+
+ @Test(dataProvider="parseStandaloneText")
+ public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
+ DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+ //-----------------------------------------------------------------------
+ public void test_parse_french_short_strict_full_noMatch() throws Exception {
+ setStrict(true);
+ ParsePosition pos = new ParsePosition(0);
+ getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+ .parseUnresolved("janvier", pos);
+ assertEquals(pos.getErrorIndex(), 0);
+ }
+
+ public void test_parse_french_short_strict_short_match() throws Exception {
+ setStrict(true);
+ ParsePosition pos = new ParsePosition(0);
+ assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+ .parseUnresolved("janv.", pos)
+ .getLong(MONTH_OF_YEAR),
+ 1L);
+ assertEquals(pos.getIndex(), 5);
+ }
+
+ //-----------------------------------------------------------------------
+
+ @Test(dataProvider="parseLenientText")
+ public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
+ setStrict(false);
+ ParsePosition pos = new ParsePosition(0);
+ DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
+ assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+ assertEquals(pos.getIndex(), input.length());
+ }
+
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="parseChronoLocalDate")
+ Object[][] provider_chronoLocalDate() {
+ return new Object[][] {
+ { HijrahDate.now() },
+ { JapaneseDate.now() },
+ { MinguoDate.now() },
+ { ThaiBuddhistDate.now() }};
+ }
+
+ private static final DateTimeFormatter fmt_chrono =
+ new DateTimeFormatterBuilder()
+ .optionalStart()
+ .appendChronologyId()
+ .appendLiteral(' ')
+ .optionalEnd()
+ .optionalStart()
+ .appendText(ChronoField.ERA, TextStyle.SHORT)
+ .appendLiteral(' ')
+ .optionalEnd()
+ .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
+ .appendLiteral('-')
+ .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
+ .appendLiteral('-')
+ .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
+ .toFormatter();
+
+ @Test(dataProvider="parseChronoLocalDate")
+ public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
+ System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
+ assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
+
+ DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
+ .withChronology(date.getChronology());
+ System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
+ assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
+ }
+}
--- a/jdk/test/java/time/test/java/time/format/TestTextPrinter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinter.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -84,8 +84,6 @@
*/
@Test
public class TestTextPrinter extends AbstractTestPrinterParser {
- static final Locale RUSSIAN = new Locale("ru");
- static final Locale FINNISH = new Locale("fi");
//-----------------------------------------------------------------------
@Test(expectedExceptions=DateTimeException.class)
@@ -213,32 +211,6 @@
{Locale.US, "e", "1", DayOfWeek.SUNDAY},
{Locale.US, "ee", "01", DayOfWeek.SUNDAY},
{Locale.US, "c", "1", DayOfWeek.SUNDAY},
-
- {Locale.UK, "e", "1", DayOfWeek.MONDAY},
- {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
- {Locale.UK, "c", "1", DayOfWeek.MONDAY},
- };
- }
-
- @DataProvider(name="print_JapaneseChronology")
- Object[][] provider_japaneseEra() {
- return new Object[][] {
- {ERA, TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
- {ERA, TextStyle.SHORT, 2, "Heisei"},
- {ERA, TextStyle.NARROW, 2, "H"},
- };
- };
-
- // Test data is dependent on localized resources.
- @DataProvider(name="print_standalone")
- Object[][] provider_StandaloneNames() {
- return new Object[][] {
- // standalone names for 2013-01-01 (Tue)
- // Locale, TemporalField, TextStyle, expected text
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, "\u044f\u043d\u0432\u0430\u0440\u044c"},
- {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
- {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, "tiistai"},
- {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, "ti"},
};
}
@@ -255,30 +227,6 @@
assertEquals(text, expected);
}
- @Test(dataProvider="print_JapaneseChronology")
- public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
- LocalDate ld = LocalDate.of(2013, 1, 31);
- getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
- assertEquals(buf.toString(), expected);
- }
-
- @Test(dataProvider="print_standalone")
- public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
- getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
- assertEquals(buf.toString(), expected);
- }
-
- //-----------------------------------------------------------------------
- public void test_print_french_long() throws Exception {
- getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
- assertEquals(buf.toString(), "janvier");
- }
-
- public void test_print_french_short() throws Exception {
- getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
- assertEquals(buf.toString(), "janv.");
- }
-
//-----------------------------------------------------------------------
public void test_toString1() throws Exception {
assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).toString(), "Text(MonthOfYear)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinterWithLocale.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * 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:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * 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 JSR-310 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.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.ERA;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.IsoFields.QUARTER_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.DateTimeException;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import test.java.time.temporal.MockFieldValue;
+
+/**
+ * Test TextPrinterParserWithLocale.
+ */
+@Test
+public class TestTextPrinterWithLocale extends AbstractTestPrinterParser {
+ static final Locale RUSSIAN = new Locale("ru");
+ static final Locale FINNISH = new Locale("fi");
+
+ //-----------------------------------------------------------------------
+ @DataProvider(name="print_DayOfWeekData")
+ Object[][] providerDayOfWeekData() {
+ return new Object[][] {
+ // Locale, pattern, expected text, input DayOfWeek
+ {Locale.US, "e", "1", DayOfWeek.SUNDAY},
+ {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+ {Locale.US, "c", "1", DayOfWeek.SUNDAY},
+
+ {Locale.UK, "e", "1", DayOfWeek.MONDAY},
+ {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+ {Locale.UK, "c", "1", DayOfWeek.MONDAY},
+ };
+ }
+
+ // Test data is dependent on localized resources.
+ @DataProvider(name="print_standalone")
+ Object[][] provider_StandaloneNames() {
+ return new Object[][] {
+ // standalone names for 2013-01-01 (Tue)
+ // Locale, TemporalField, TextStyle, expected text
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE, "\u044f\u043d\u0432\u0430\u0440\u044c"},
+ {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
+ {FINNISH, DAY_OF_WEEK, TextStyle.FULL_STANDALONE, "tiistai"},
+ {FINNISH, DAY_OF_WEEK, TextStyle.SHORT_STANDALONE, "ti"},
+ };
+ }
+
+ @Test(dataProvider="print_DayOfWeekData")
+ public void test_formatDayOfWeek(Locale locale, String pattern, String expected, DayOfWeek dayOfWeek) {
+ DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+ String text = formatter.format(dayOfWeek);
+ assertEquals(text, expected);
+ }
+
+ @Test(dataProvider="print_standalone")
+ public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
+ getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
+ assertEquals(buf.toString(), expected);
+ }
+
+ //-----------------------------------------------------------------------
+ public void test_print_french_long() throws Exception {
+ getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+ assertEquals(buf.toString(), "janvier");
+ }
+
+ public void test_print_french_short() throws Exception {
+ getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+ assertEquals(buf.toString(), "janv.");
+ }
+
+ @DataProvider(name="print_JapaneseChronology")
+ Object[][] provider_japaneseEra() {
+ return new Object[][] {
+ {ERA, TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
+ {ERA, TextStyle.SHORT, 2, "Heisei"},
+ {ERA, TextStyle.NARROW, 2, "H"},
+ };
+ };
+
+ @Test(dataProvider="print_JapaneseChronology")
+ public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+ LocalDate ld = LocalDate.of(2013, 1, 31);
+ getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
+ assertEquals(buf.toString(), expected);
+ }
+}
--- a/jdk/test/java/util/Collection/SetFactories.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/util/Collection/SetFactories.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -103,6 +103,8 @@
hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i")),
a( Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+ a( Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+ Set.of("j", "i", "h", "g", "f", "e", "d", "c", "b", "a")),
a( Set.of(stringArray),
hashSetOf(stringArray))
).iterator();
@@ -183,6 +185,17 @@
Set<String> set = Set.of(array);
}
+ @Test(dataProvider="all")
+ public void hashCodeEqual(Set<String> act, Set<String> exp) {
+ assertEquals(act.hashCode(), exp.hashCode());
+ }
+
+ @Test(dataProvider="all")
+ public void containsAll(Set<String> act, Set<String> exp) {
+ assertTrue(act.containsAll(exp));
+ assertTrue(exp.containsAll(act));
+ }
+
@Test(expectedExceptions=NullPointerException.class)
public void nullDisallowed1() {
Set.of((String)null); // force one-arg overload
--- a/jdk/test/java/util/Map/MapFactories.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/java/util/Map/MapFactories.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -103,6 +103,8 @@
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h"), genMap(8)),
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i"), genMap(9)),
a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"), genMap(10)),
+ a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"),
+ Map.of(4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 0, "a", 1, "b", 2, "c", 3, "d")),
a(Map.ofEntries(genEntries(MAX_ENTRIES)), genMap(MAX_ENTRIES))
).iterator();
}
@@ -135,6 +137,18 @@
assertEquals(act, exp);
}
+ @Test(dataProvider="all")
+ public void containsAllKeys(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertTrue(act.keySet().containsAll(exp.keySet()));
+ assertTrue(exp.keySet().containsAll(act.keySet()));
+ }
+
+ @Test(dataProvider="all")
+ public void containsAllValues(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertTrue(act.values().containsAll(exp.values()));
+ assertTrue(exp.values().containsAll(act.values()));
+ }
+
@Test(expectedExceptions=IllegalArgumentException.class)
public void dupKeysDisallowed2() {
Map<Integer, String> map = Map.of(0, "a", 0, "b");
@@ -192,6 +206,11 @@
Map<Integer, String> map = Map.ofEntries(entries);
}
+ @Test(dataProvider="all")
+ public void hashCodeEquals(Map<Integer,String> act, Map<Integer,String> exp) {
+ assertEquals(act.hashCode(), exp.hashCode());
+ }
+
@Test(expectedExceptions=NullPointerException.class)
public void nullKeyDisallowed1() {
Map<Integer, String> map = Map.of(null, "a");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/8133919/DrawGridLinesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,103 @@
+/*
+ * 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.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableModel;
+
+/*
+ * @test
+ * @bug 8133919
+ * @summary [macosx] JTable grid lines are incorrectly positioned on HiDPI display
+ * @run main DrawGridLinesTest
+ */
+public class DrawGridLinesTest {
+
+ private static final int WIDTH = 300;
+ private static final int HEIGHT = 150;
+ private static final Color GRID_COLOR = Color.BLACK;
+ private static final Color TABLE_BACKGROUND_COLOR = Color.BLUE;
+ private static final Color CELL_RENDERER_BACKGROUND_COLOR = Color.YELLOW;
+ private static final int SCALE = 2;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(DrawGridLinesTest::checkTableGridLines);
+ }
+
+ private static void checkTableGridLines() {
+
+ TableModel dataModel = new AbstractTableModel() {
+ public int getColumnCount() {
+ return 10;
+ }
+
+ public int getRowCount() {
+ return 10;
+ }
+
+ public Object getValueAt(int row, int col) {
+ return " ";
+ }
+ };
+
+ DefaultTableCellRenderer r = new DefaultTableCellRenderer();
+ r.setOpaque(true);
+ r.setBackground(CELL_RENDERER_BACKGROUND_COLOR);
+
+ JTable table = new JTable(dataModel);
+ table.setSize(WIDTH, HEIGHT);
+ table.setDefaultRenderer(Object.class, r);
+ table.setGridColor(GRID_COLOR);
+ table.setShowGrid(true);
+ table.setShowHorizontalLines(true);
+ table.setShowVerticalLines(true);
+ table.setBackground(TABLE_BACKGROUND_COLOR);
+
+ checkTableGridLines(table);
+ }
+
+ private static void checkTableGridLines(JTable table) {
+
+ int w = SCALE * WIDTH;
+ int h = SCALE * HEIGHT;
+
+ BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = img.createGraphics();
+ g.scale(SCALE, SCALE);
+ table.paint(g);
+ g.dispose();
+
+ int size = Math.min(w, h);
+ int rgb = TABLE_BACKGROUND_COLOR.getRGB();
+
+ for (int i = 0; i < size; i++) {
+ if (img.getRGB(i, i) == rgb || img.getRGB(i, size - i - 1) == rgb) {
+ throw new RuntimeException("Artifacts in the table background color!");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/PrintManualTest_FitWidthMultiple.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,218 @@
+/*
+ * 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 8170349
+ * @summary Verify if printed content is within border and all columns are
+ * printed for PrintMode.FIT_WIDTH
+ * @run main/manual PrintManualTest_FitWidthMultiple
+ */
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.text.MessageFormat;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+public class PrintManualTest_FitWidthMultiple extends JTable implements Runnable {
+
+ static boolean testPassed;
+ static JFrame fr = null;
+ static JFrame instructFrame = null;
+ private final CountDownLatch latch;
+
+ public PrintManualTest_FitWidthMultiple(CountDownLatch latch){
+ this.latch = latch;
+ }
+
+ @Override
+ public void run() {
+ try {
+ createUIandTest();
+ } catch (Exception ex) {
+ dispose();
+ latch.countDown();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ private void createUIandTest() throws Exception {
+ /*Message Format Header and Footer */
+ final MessageFormat header=new MessageFormat("JTable Printing Header {0}");
+ final MessageFormat footer = new MessageFormat("JTable Printing Footer {0}");
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ /* Instructions Section */
+ String info =
+ " \nThis test case brings up JTable with more Columns and Rows \n"+
+ "Press the Print Button. It Prints in PRINT_MODE_FIT_WIDTH \n" +
+ "It Pops up the Print Dialog. Check if Job/Print Attributes in the\n" +
+ "Print Dialog are configurable. Default Print out will be in Landscape \n"+
+ "The Print out should have JTable Centered on the Print out with thin borders \n"+
+ "Prints out with Header and Footer. \n"+
+ "The JTable should have all columns printed within border";
+
+ instructFrame=new JFrame("PrintManualTest_NormalSingle");
+ JPanel panel=new JPanel(new BorderLayout());
+ JButton button1 = new JButton("Pass");
+ JButton button2 = new JButton("Fail");
+ button1.addActionListener((e) -> {
+ testPassed = true;
+ dispose();
+ latch.countDown();
+ });
+ button2.addActionListener((e) -> {
+ testPassed = false;
+ dispose();
+ latch.countDown();
+ });
+ JPanel btnpanel1 = new JPanel();
+ btnpanel1.add(button1);
+ btnpanel1.add(button2);
+ panel.add(addInfo(info),BorderLayout.CENTER);
+ panel.add(btnpanel1, BorderLayout.SOUTH);
+ instructFrame.getContentPane().add(panel);
+ instructFrame.setBounds(600,100,350,350);
+
+ /* Print Button */
+ final JButton printButton=new JButton("Print");
+
+ /* Table Model */
+ final TableModel datamodel=new AbstractTableModel(){
+ @Override
+ public int getColumnCount() { return 50;}
+ @Override
+ public int getRowCount() { return 50; }
+ @Override
+ public Object getValueAt(int row, int column){ return new Integer(row*column);}
+ };
+
+ /* Constructing the JTable */
+ final JTable table=new JTable(datamodel);
+
+ /* Putting the JTable in ScrollPane and Frame Container */
+ JScrollPane scrollpane=new JScrollPane(table);
+ fr = new JFrame("PrintManualTest_FitWidthMultiple");
+ fr.getContentPane().add(scrollpane);
+
+ /* Light Weight Panel for holding Print and other buttons */
+ JPanel btnpanel=new JPanel();
+ btnpanel.add(printButton);
+ fr.getContentPane().add(btnpanel,BorderLayout.SOUTH);
+ fr.setBounds(0,0,400,400);
+ fr.setSize(500,500);
+
+ /* Binding the KeyStroke to Print Button Action */
+ fr.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ctrl P"), "printButton");
+ fr.getRootPane().getActionMap().put("printButton", new AbstractAction(){
+ @Override
+ public void actionPerformed(ActionEvent e){
+ printButton.doClick();
+ }
+ });
+
+ /* Container and Component Listeners */
+ fr.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ dispose();
+ if (testPassed == false) {
+ throw new RuntimeException(" User has not executed the test");
+ }
+ }
+ });
+
+ final PrintRequestAttributeSet prattr=new HashPrintRequestAttributeSet();
+ prattr.add(javax.print.attribute.standard.OrientationRequested.LANDSCAPE);
+
+ printButton.addActionListener(new ActionListener(){
+ @Override
+ public void actionPerformed(ActionEvent ae){
+ try{
+ table.print(JTable.PrintMode.FIT_WIDTH, header,footer,true,prattr,true);
+ } catch(Exception e){}
+ }
+ });
+ instructFrame.setVisible(true);
+ fr.setVisible(true);
+ }
+ });
+ }
+
+ public void dispose() {
+ instructFrame.dispose();
+ fr.dispose();
+ }
+
+ public JScrollPane addInfo(String info) {
+ JTextArea jta = new JTextArea(info,8,20);
+ jta.setEditable(false);
+ jta.setLineWrap(true);
+ JScrollPane sp = new JScrollPane(jta);
+ return sp;
+
+ }
+
+ /* Main Method */
+
+ public static void main(String[] argv) throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ PrintManualTest_FitWidthMultiple test = new PrintManualTest_FitWidthMultiple(latch);
+ Thread T1 = new Thread(test);
+ T1.start();
+
+ // wait for latch to complete
+ boolean ret = false;
+ try {
+ ret = latch.await(60, TimeUnit.SECONDS);
+ } catch (InterruptedException ie) {
+ throw ie;
+ }
+ if (!ret) {
+ test.dispose();
+ throw new RuntimeException(" User has not executed the test");
+ }
+ if (test.testPassed == false) {
+ throw new RuntimeException("printed contents is beyond borders");
+ }
+ }
+}
--- a/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -42,7 +42,7 @@
/**
* @test
- * @bug 8156217
+ * @bug 8156217 8169922
* @key headful
* @summary Selected text is shifted on HiDPI display
* @run main FPMethodCalledTest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017, 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 8159058
+ * @summary Test that empty default namespace declaration clears the
+ * default namespace value
+ * @modules java.xml.ws/com.sun.xml.internal.ws.api
+ * java.xml.ws/com.sun.xml.internal.ws.api.message.saaj
+ * java.xml.ws/com.sun.xml.internal.ws.message.stream
+ * @run testng/othervm SaajEmptyNamespaceTest
+ */
+
+import com.sun.xml.internal.ws.api.SOAPVersion;
+import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory;
+import com.sun.xml.internal.ws.message.stream.StreamMessage;
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.w3c.dom.Node;
+
+public class SaajEmptyNamespaceTest {
+
+ /*
+ * Test that SOAP message with default namespace declaration that contains empty
+ * string is properly processed by SAAJ reader.
+ */
+ @Test
+ public void testResetDefaultNamespaceSAAJ() throws Exception {
+ // Create SOAP message from XML string and process it with SAAJ reader
+ XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader(
+ new StringReader(INPUT_SOAP_MESSAGE));
+ StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11,
+ envelope, null);
+ SAAJFactory saajFact = new SAAJFactory();
+ SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage);
+
+ // Check if constructed object model meets local names and namespace expectations
+ SOAPElement request = (SOAPElement) soapMessage.getSOAPBody().getFirstChild();
+ // Check top body element name
+ Assert.assertEquals(request.getLocalName(), "SampleServiceRequest");
+ // Check top body element namespace
+ Assert.assertEquals(request.getNamespaceURI(), TEST_NS);
+ SOAPElement params = (SOAPElement) request.getFirstChild();
+ // Check first child name
+ Assert.assertEquals(params.getLocalName(), "RequestParams");
+ // Check if first child namespace is null
+ Assert.assertNull(params.getNamespaceURI());
+
+ // Check inner elements of the first child
+ SOAPElement param1 = (SOAPElement) params.getFirstChild();
+ Assert.assertEquals(param1.getLocalName(), "Param1");
+ Assert.assertNull(param1.getNamespaceURI());
+ SOAPElement param2 = (SOAPElement) params.getChildNodes().item(1);
+ Assert.assertEquals(param2.getLocalName(), "Param2");
+ Assert.assertNull(param2.getNamespaceURI());
+ // Check full content of SOAP body
+ Assert.assertEquals(nodeToText(request), EXPECTED_RESULT);
+ }
+
+ /*
+ * Test that adding element with explicitly null namespace URI shall put the
+ * element into global namespace. Namespace declarations are not added explicitly.
+ */
+ @Test
+ public void testAddElementToNullNsNoDeclarations() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI shall put
+ * the element into global namespace. Namespace declarations are not added
+ * explicitly.
+ */
+ @Test
+ public void testAddElementToGlobalNsNoDeclarations() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI set via QName
+ * shall put the element into global namespace.
+ */
+ @Test
+ public void testAddElementToNullNsQName() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName(null, "global-child"));
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI shall put
+ * the element into global namespace.
+ */
+ @Test
+ public void testAddElementToGlobalNs() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+ }
+
+ /*
+ * Test that adding element with explicitly null namespace URI shall put
+ * the element into global namespace.
+ */
+ @Test
+ public void testAddElementToNullNs() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+ childGlobalNS.addNamespaceDeclaration("", null);
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(TEST_NS, childDefaultNS.getNamespaceURI());
+ }
+
+ /*
+ * Test that adding element with explicitly empty namespace URI via QName
+ * shall put the element in global namespace.
+ */
+ @Test
+ public void testAddElementToGlobalNsQName() throws Exception {
+ // Create empty SOAP message
+ SOAPMessage msg = createSoapMessage();
+ SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+ // Add elements
+ SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+ parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+ SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName("", "global-child"));
+ childGlobalNS.addNamespaceDeclaration("", "");
+ SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+ SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+ // Check namespace URIs
+ Assert.assertNull(childGlobalNS.getNamespaceURI());
+ Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+ Assert.assertEquals(childDefaultNS.getNamespaceURI(),TEST_NS);
+ }
+
+ // Convert DOM node to text representation
+ private String nodeToText(Node node) throws TransformerException {
+ Transformer trans = TransformerFactory.newInstance().newTransformer();
+ trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ StringWriter writer = new StringWriter();
+ StreamResult result = new StreamResult(writer);
+ trans.transform(new DOMSource(node), result);
+ String bodyContent = writer.toString();
+ System.out.println("SOAP body content read by SAAJ:"+bodyContent);
+ return bodyContent;
+ }
+
+ // Create SOAP message with empty body
+ private static SOAPMessage createSoapMessage() throws SOAPException, UnsupportedEncodingException {
+ String xml = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ +"<SOAP-ENV:Body/></SOAP-ENV:Envelope>";
+ MessageFactory mFactory = MessageFactory.newInstance();
+ SOAPMessage msg = mFactory.createMessage();
+ msg.getSOAPPart().setContent(new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
+ return msg;
+ }
+
+ // Namespace value used in tests
+ private static String TEST_NS = "http://example.org/test";
+
+ // Content of SOAP message passed to SAAJ factory
+ private static String INPUT_SOAP_MESSAGE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ + "<s:Body>"
+ + "<SampleServiceRequest xmlns=\"http://example.org/test\""
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<RequestParams xmlns=\"\">"
+ + "<Param1>hogehoge</Param1>"
+ + "<Param2>fugafuga</Param2>"
+ + "</RequestParams>"
+ + "</SampleServiceRequest>"
+ + "</s:Body>"
+ + "</s:Envelope>";
+
+ // Expected body content after SAAJ processing
+ private static String EXPECTED_RESULT = "<SampleServiceRequest"
+ +" xmlns=\"http://example.org/test\">"
+ + "<RequestParams xmlns=\"\">"
+ + "<Param1>hogehoge</Param1>"
+ + "<Param2>fugafuga</Param2>"
+ + "</RequestParams>"
+ + "</SampleServiceRequest>";
+}
--- a/jdk/test/lib/security/SecurityTools.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * 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.Collections;
-import java.util.List;
-import jdk.testlibrary.JDKToolLauncher;
-import jdk.testlibrary.OutputAnalyzer;
-import jdk.testlibrary.ProcessTools;
-
-public class SecurityTools {
-
- public static final String NO_ALIAS = null;
-
- // keytool
-
- public static OutputAnalyzer keytool(List<String> options)
- throws Throwable {
-
- JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("keytool")
- .addVMArg("-Duser.language=en")
- .addVMArg("-Duser.country=US");
- for (String option : options) {
- if (option.startsWith("-J")) {
- launcher.addVMArg(option.substring(2));
- } else {
- launcher.addToolArg(option);
- }
- }
- return ProcessTools.executeCommand(launcher.getCommand());
- }
-
- public static OutputAnalyzer keytool(String options) throws Throwable {
- return keytool(options.split("\\s+"));
- }
-
- public static OutputAnalyzer keytool(String... options) throws Throwable {
- return keytool(List.of(options));
- }
-
- // jarsigner
-
- public static OutputAnalyzer jarsigner(String jar, String alias,
- List<String> options) throws Throwable {
- JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
- .addVMArg("-Duser.language=en")
- .addVMArg("-Duser.country=US");
- for (String option : options) {
- if (option.startsWith("-J")) {
- launcher.addVMArg(option.substring(2));
- } else {
- launcher.addToolArg(option);
- }
- }
- launcher.addToolArg(jar);
- if (alias != null) {
- launcher.addToolArg(alias);
- }
- return ProcessTools.executeCommand(launcher.getCommand());
- }
-
- public static OutputAnalyzer jarsigner(String jar, String alias,
- String options) throws Throwable {
-
- return jarsigner(jar, alias, options.split("\\s+"));
- }
-
- public static OutputAnalyzer jarsigner(String jar, String alias,
- String... options) throws Throwable {
-
- return jarsigner(jar, alias, List.of(options));
- }
-
- public static OutputAnalyzer sign(String jar, String alias, String... options)
- throws Throwable {
-
- return jarsigner(jar, alias,
- mergeOptions("-J-Djava.security.egd=file:/dev/./urandom", options));
- }
-
- public static OutputAnalyzer verify(String jar, String... options)
- throws Throwable {
-
- return jarsigner(jar, NO_ALIAS, mergeOptions("-verify", options));
- }
-
- // helper methods
-
- private static List<String> mergeOptions(
- String firstOption, String... secondPart) {
-
- return mergeOptions(List.of(firstOption), secondPart);
- }
-
- private static List<String> mergeOptions(
- List<String> firstPart, String... secondPart) {
-
- List<String> options = new ArrayList<>(firstPart);
- Collections.addAll(options, secondPart);
- return options;
- }
-}
--- a/jdk/test/sun/net/www/protocol/http/SetIfModifiedSince.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/net/www/protocol/http/SetIfModifiedSince.java Tue Jan 24 00:30:23 2017 +0100
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 4213164
+ @bug 4213164 8172253
@summary setIfModifiedSince mehtod in HttpURLConnection sometimes fails
*/
import java.util.*;
@@ -88,7 +88,7 @@
//url = new URL(args[0]);
url = new URL("http://localhost:" + String.valueOf(port) +
"/anything");
- con = (HttpURLConnection)url.openConnection();
+ con = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
con.setIfModifiedSince(date.getTime());
con.connect();
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -29,7 +29,7 @@
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
* java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
* @run main/othervm DeadCachedConnection
*/
@@ -100,7 +100,7 @@
public static int makeRegistry(int port) {
try {
- subreg = REGISTRY.createREGISTRY(System.out, System.err, "", port);
+ subreg = RegistryVM.createRegistryVM(System.out, System.err, "", port);
subreg.start();
int regPort = subreg.getPort();
System.out.println("Starting registry on port " + regPort);
@@ -113,11 +113,11 @@
return -1;
}
- private static REGISTRY subreg = null;
+ private static RegistryVM subreg = null;
public static void killRegistry() throws InterruptedException {
if (subreg != null) {
- subreg.shutdown();
+ subreg.cleanup();
subreg = null;
}
}
--- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
import java.security.*;
import java.security.cert.*;
-import java.security.cert.Certificate;
import javax.net.ssl.*;
@@ -61,6 +60,8 @@
private static PeerFactory peerFactory;
+ static final CountDownLatch clientCondition = new CountDownLatch(1);
+
static abstract class Server implements Runnable {
final CipherTest cipherTest;
@@ -313,6 +314,10 @@
}
threads[i].start();
}
+
+ // The client threads are ready.
+ clientCondition.countDown();
+
try {
for (int i = 0; i < THREADS; i++) {
threads[i].join();
@@ -367,6 +372,10 @@
try {
runTest(params);
System.out.println("Passed " + params);
+ } catch (SocketTimeoutException ste) {
+ System.out.println("The client connects to the server timeout, "
+ + "so ignore the test.");
+ break;
} catch (Exception e) {
cipherTest.setFailed();
System.out.println("** Failed " + params + "**");
--- a/jdk/test/sun/security/pkcs11/sslecc/JSSEClient.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/security/pkcs11/sslecc/JSSEClient.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,7 @@
import java.io.*;
import java.net.*;
-import java.util.*;
-import java.security.*;
-import java.security.cert.*;
import java.security.cert.Certificate;
import javax.net.ssl.*;
@@ -46,10 +43,30 @@
SSLSocket socket = null;
try {
keyManager.setAuthType(params.clientAuth);
- sslContext.init(new KeyManager[] {keyManager}, new TrustManager[] {cipherTest.trustManager}, cipherTest.secureRandom);
- SSLSocketFactory factory = (SSLSocketFactory)sslContext.getSocketFactory();
- socket = (SSLSocket)factory.createSocket("127.0.0.1", cipherTest.serverPort);
- socket.setSoTimeout(cipherTest.TIMEOUT);
+ sslContext.init(
+ new KeyManager[] { keyManager },
+ new TrustManager[] { CipherTest.trustManager },
+ CipherTest.secureRandom);
+ SSLSocketFactory factory
+ = (SSLSocketFactory) sslContext.getSocketFactory();
+
+ socket = (SSLSocket) factory.createSocket();
+ try {
+ socket.connect(new InetSocketAddress("127.0.0.1",
+ CipherTest.serverPort), 15000);
+ } catch (IOException ioe) {
+ // The server side may be impacted by naughty test cases or
+ // third party routines, and cannot accept connections.
+ //
+ // Just ignore the test if the connection cannot be
+ // established.
+ System.out.println(
+ "Cannot make a connection in 15 seconds. " +
+ "Ignore in client side.");
+ return;
+ }
+
+ socket.setSoTimeout(CipherTest.TIMEOUT);
socket.setEnabledCipherSuites(new String[] {params.cipherSuite});
socket.setEnabledProtocols(new String[] {params.protocol});
InputStream in = socket.getInputStream();
--- a/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,11 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.SocketTimeoutException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
@@ -40,24 +43,37 @@
JSSEServer(CipherTest cipherTest) throws Exception {
super(cipherTest);
SSLContext serverContext = SSLContext.getInstance("TLS");
- serverContext.init(new KeyManager[] {cipherTest.keyManager}, new TrustManager[] {cipherTest.trustManager}, cipherTest.secureRandom);
+ serverContext.init(
+ new KeyManager[] { CipherTest.keyManager },
+ new TrustManager[] { CipherTest.trustManager },
+ CipherTest.secureRandom);
SSLServerSocketFactory factory = (SSLServerSocketFactory)serverContext.getServerSocketFactory();
serverSocket = (SSLServerSocket)factory.createServerSocket(0);
- cipherTest.serverPort = serverSocket.getLocalPort();
+ serverSocket.setSoTimeout(CipherTest.TIMEOUT);
+ CipherTest.serverPort = serverSocket.getLocalPort();
serverSocket.setEnabledCipherSuites(factory.getSupportedCipherSuites());
serverSocket.setWantClientAuth(true);
}
@Override
public void run() {
- System.out.println("JSSE Server listening on port " + cipherTest.serverPort);
+ System.out.println("JSSE Server listening on port " + CipherTest.serverPort);
Executor exec = Executors.newFixedThreadPool
(CipherTest.THREADS, DaemonThreadFactory.INSTANCE);
+
try {
+ if (!CipherTest.clientCondition.await(CipherTest.TIMEOUT,
+ TimeUnit.MILLISECONDS)) {
+ System.out.println(
+ "The client is not the expected one or timeout. "
+ + "Ignore in server side.");
+ return;
+ }
+
while (true) {
final SSLSocket socket = (SSLSocket)serverSocket.accept();
- socket.setSoTimeout(cipherTest.TIMEOUT);
+ socket.setSoTimeout(CipherTest.TIMEOUT);
Runnable r = new Runnable() {
@Override
public void run() {
@@ -86,11 +102,12 @@
};
exec.execute(r);
}
- } catch (IOException e) {
+ } catch (SocketTimeoutException ste) {
+ System.out.println("The server got timeout for waiting for the connection, "
+ + "so ignore the test.");
+ } catch (Exception e) {
cipherTest.setFailed();
e.printStackTrace();
- //
}
}
-
}
--- a/jdk/test/sun/security/tools/keytool/PrintSSL.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/security/tools/keytool/PrintSSL.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,7 @@
* @test
* @bug 6480981 8160624
* @summary keytool should be able to import certificates from remote SSL server
- * @library /lib/security
- * @library /lib/testlibrary
+ * @library /test/lib
* @run main/othervm PrintSSL
*/
@@ -36,7 +35,8 @@
import java.util.concurrent.CountDownLatch;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
-import jdk.testlibrary.OutputAnalyzer;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
public class PrintSSL {
--- a/jdk/test/sun/security/tools/keytool/ReadJar.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/sun/security/tools/keytool/ReadJar.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,15 @@
* @test
* @bug 6890872 8168882
* @summary keytool -printcert to recognize signed jar files
- * @library /lib/security
+ * @library /test/lib
* @library /lib/testlibrary
*/
import java.nio.file.Files;
import java.nio.file.Paths;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
import jdk.testlibrary.JarUtils;
-import jdk.testlibrary.OutputAnalyzer;
public class ReadJar {
--- a/jdk/test/tools/jar/InputFilesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/tools/jar/InputFilesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -102,6 +102,7 @@
"META-INF/MANIFEST.MF" + nl +
"testfile1" + nl +
"testfile2" + nl +
+ "META-INF/versions/9/" + nl +
"META-INF/versions/9/testfile3" + nl +
"META-INF/versions/9/testfile4" + nl;
rm("test.jar test1 test2 test3 test4");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/Basic.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2016, 2017, 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 8146486 8172432
+ * @summary Fail to create a MR modular JAR with a versioned entry in
+ * base-versioned empty package
+ * @modules java.base/jdk.internal.module
+ * jdk.compiler
+ * jdk.jartool
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.FileUtils
+ * @run testng Basic
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Version;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipFile;
+
+import jdk.internal.module.ModuleInfoExtender;
+import jdk.testlibrary.FileUtils;
+
+public class Basic {
+ private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() -> new RuntimeException("jar tool not found"));
+ private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac")
+ .orElseThrow(() -> new RuntimeException("javac tool not found"));
+ private final String linesep = System.lineSeparator();
+ private final Path testsrc;
+ private final Path userdir;
+ private final ByteArrayOutputStream outbytes = new ByteArrayOutputStream();
+ private final PrintStream out = new PrintStream(outbytes, true);
+ private final ByteArrayOutputStream errbytes = new ByteArrayOutputStream();
+ private final PrintStream err = new PrintStream(errbytes, true);
+
+ public Basic() throws IOException {
+ testsrc = Paths.get(System.getProperty("test.src"));
+ userdir = Paths.get(System.getProperty("user.dir", "."));
+
+ // compile the classes directory
+ Path source = testsrc.resolve("src").resolve("classes");
+ Path destination = Paths.get("classes");
+ javac(source, destination);
+
+ // compile the mr9 directory including module-info.java
+ source = testsrc.resolve("src").resolve("mr9");
+ destination = Paths.get("mr9");
+ javac(source, destination);
+
+ // move module-info.class for later use
+ Files.move(destination.resolve("module-info.class"),
+ Paths.get("module-info.class"));
+ }
+
+ private void javac(Path source, Path destination) throws IOException {
+ String[] args = Stream.concat(
+ Stream.of("-d", destination.toString()),
+ Files.walk(source)
+ .map(Path::toString)
+ .filter(s -> s.endsWith(".java"))
+ ).toArray(String[]::new);
+ JAVAC_TOOL.run(System.out, System.err, args);
+ }
+
+ private int jar(String cmd) {
+ outbytes.reset();
+ errbytes.reset();
+ return JAR_TOOL.run(out, err, cmd.split(" +"));
+ }
+
+ @AfterClass
+ public void cleanup() throws IOException {
+ Files.walk(userdir, 1)
+ .filter(p -> !p.equals(userdir))
+ .forEach(p -> {
+ try {
+ if (Files.isDirectory(p)) {
+ FileUtils.deleteFileTreeWithRetry(p);
+ } else {
+ FileUtils.deleteFileIfExistsWithRetry(p);
+ }
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ });
+ }
+
+ // updates a valid multi-release jar with a new public class in
+ // versioned section and fails
+ @Test
+ public void test1() {
+ // successful build of multi-release jar
+ int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
+ Assert.assertEquals(rc, 0);
+
+ jar("-tf mmr.jar");
+
+ Set<String> actual = lines(outbytes);
+ Set<String> expected = Set.of(
+ "META-INF/",
+ "META-INF/MANIFEST.MF",
+ "p/",
+ "p/Hi.class",
+ "META-INF/versions/9/p/Hi.class"
+ );
+ Assert.assertEquals(actual, expected);
+
+ // failed build because of new public class
+ rc = jar("-uf mmr.jar --release 9 -C mr9 p/internal/Bar.class");
+ Assert.assertEquals(rc, 1);
+
+ String s = new String(errbytes.toByteArray());
+ Assert.assertTrue(Message.NOT_FOUND_IN_BASE_ENTRY.match(s, "p/internal/Bar.class"));
+ }
+
+ // updates a valid multi-release jar with a module-info class and new
+ // concealed public class in versioned section and succeeds
+ @Test
+ public void test2() {
+ // successful build of multi-release jar
+ int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
+ Assert.assertEquals(rc, 0);
+
+ // successful build because of module-info and new public class
+ rc = jar("-uf mmr.jar module-info.class --release 9 -C mr9 p/internal/Bar.class");
+ Assert.assertEquals(rc, 0);
+
+ String s = new String(errbytes.toByteArray());
+ Assert.assertTrue(Message.NEW_CONCEALED_PACKAGE_WARNING.match(s, "p/internal/Bar.class"));
+
+ jar("-tf mmr.jar");
+
+ Set<String> actual = lines(outbytes);
+ Set<String> expected = Set.of(
+ "META-INF/",
+ "META-INF/MANIFEST.MF",
+ "p/",
+ "p/Hi.class",
+ "META-INF/versions/9/p/Hi.class",
+ "META-INF/versions/9/p/internal/Bar.class",
+ "module-info.class"
+ );
+ Assert.assertEquals(actual, expected);
+ }
+
+ // jar tool fails building mmr.jar because of new public class
+ @Test
+ public void test3() {
+ int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 .");
+ Assert.assertEquals(rc, 1);
+
+ String s = new String(errbytes.toByteArray());
+ Assert.assertTrue(Message.NOT_FOUND_IN_BASE_ENTRY.match(s, "p/internal/Bar.class"));
+ }
+
+ // jar tool succeeds building mmr.jar because of concealed package
+ @Test
+ public void test4() {
+ int rc = jar("-cf mmr.jar module-info.class -C classes . " +
+ "--release 9 module-info.class -C mr9 .");
+ Assert.assertEquals(rc, 0);
+
+ String s = new String(errbytes.toByteArray());
+ Assert.assertTrue(Message.NEW_CONCEALED_PACKAGE_WARNING.match(s, "p/internal/Bar.class"));
+
+ jar("-tf mmr.jar");
+
+ Set<String> actual = lines(outbytes);
+ Set<String> expected = Set.of(
+ "META-INF/",
+ "META-INF/MANIFEST.MF",
+ "module-info.class",
+ "META-INF/versions/9/module-info.class",
+ "p/",
+ "p/Hi.class",
+ "META-INF/versions/9/",
+ "META-INF/versions/9/p/",
+ "META-INF/versions/9/p/Hi.class",
+ "META-INF/versions/9/p/internal/",
+ "META-INF/versions/9/p/internal/Bar.class"
+ );
+ Assert.assertEquals(actual, expected);
+ }
+
+ // jar tool does two updates, no exported packages, all concealed
+ @Test
+ public void test5() throws IOException {
+ // compile the mr10 directory
+ Path source = testsrc.resolve("src").resolve("mr10");
+ Path destination = Paths.get("mr10");
+ javac(source, destination);
+
+ // create a directory for this tests special files
+ Files.createDirectory(Paths.get("test5"));
+
+ // create an empty module-info.java
+ String hi = "module hi {" + linesep + "}" + linesep;
+ Path modinfo = Paths.get("test5", "module-info.java");
+ Files.write(modinfo, hi.getBytes());
+
+ // and compile it
+ javac(modinfo, Paths.get("test5"));
+
+ int rc = jar("--create --file mr.jar -C classes .");
+ Assert.assertEquals(rc, 0);
+
+ rc = jar("--update --file mr.jar -C test5 module-info.class"
+ + " --release 9 -C mr9 .");
+ Assert.assertEquals(rc, 0);
+
+ jar("tf mr.jar");
+
+ Set<String> actual = lines(outbytes);
+ Set<String> expected = Set.of(
+ "META-INF/",
+ "META-INF/MANIFEST.MF",
+ "p/",
+ "p/Hi.class",
+ "META-INF/versions/9/",
+ "META-INF/versions/9/p/",
+ "META-INF/versions/9/p/Hi.class",
+ "META-INF/versions/9/p/internal/",
+ "META-INF/versions/9/p/internal/Bar.class",
+ "module-info.class"
+ );
+ Assert.assertEquals(actual, expected);
+
+ jar("-d --file mr.jar");
+
+ actual = lines(outbytes);
+ expected = Set.of(
+ "hi",
+ "requires mandated java.base",
+ "contains p",
+ "contains p.internal"
+ );
+ Assert.assertEquals(actual, expected);
+
+ rc = jar("--update --file mr.jar --release 10 -C mr10 .");
+ Assert.assertEquals(rc, 0);
+
+ jar("tf mr.jar");
+
+ actual = lines(outbytes);
+ expected = Set.of(
+ "META-INF/",
+ "META-INF/MANIFEST.MF",
+ "p/",
+ "p/Hi.class",
+ "META-INF/versions/9/",
+ "META-INF/versions/9/p/",
+ "META-INF/versions/9/p/Hi.class",
+ "META-INF/versions/9/p/internal/",
+ "META-INF/versions/9/p/internal/Bar.class",
+ "META-INF/versions/10/",
+ "META-INF/versions/10/p/",
+ "META-INF/versions/10/p/internal/",
+ "META-INF/versions/10/p/internal/bar/",
+ "META-INF/versions/10/p/internal/bar/Gee.class",
+ "module-info.class"
+ );
+ Assert.assertEquals(actual, expected);
+
+ jar("-d --file mr.jar");
+
+ actual = lines(outbytes);
+ expected = Set.of(
+ "hi",
+ "requires mandated java.base",
+ "contains p",
+ "contains p.internal",
+ "contains p.internal.bar"
+ );
+ Assert.assertEquals(actual, expected);
+ }
+
+ // root and versioned module-info entries have different main-class, version
+ // attributes
+ @Test
+ public void test6() throws IOException {
+ // create a directory for this tests special files
+ Files.createDirectory(Paths.get("test6"));
+ Files.createDirectory(Paths.get("test6-v9"));
+
+ // compile the classes directory
+ Path src = testsrc.resolve("src").resolve("classes");
+ Path dst = Paths.get("test6");
+ javac(src, dst);
+
+ byte[] mdBytes = Files.readAllBytes(Paths.get("module-info.class"));
+
+ ModuleInfoExtender mie = ModuleInfoExtender.newExtender(
+ new ByteArrayInputStream(mdBytes));
+
+ mie.mainClass("foo.main");
+ mie.version(Version.parse("1.0"));
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mie.write(baos);
+ Files.write(Paths.get("test6", "module-info.class"), baos.toByteArray());
+ Files.write(Paths.get("test6-v9", "module-info.class"), baos.toByteArray());
+
+ int rc = jar("--create --file mmr.jar -C test6 . --release 9 -C test6-v9 .");
+ Assert.assertEquals(rc, 0);
+
+
+ // different main-class
+ mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
+ mie.mainClass("foo.main2");
+ mie.version(Version.parse("1.0"));
+ baos.reset();
+ mie.write(baos);
+ Files.write(Paths.get("test6-v9", "module-info.class"), baos.toByteArray());
+
+ rc = jar("--create --file mmr.jar -C test6 . --release 9 -C test6-v9 .");
+ Assert.assertEquals(rc, 1);
+
+ Assert.assertTrue(Message.CONTAINS_DIFFERENT_MAINCLASS.match(
+ new String(errbytes.toByteArray()),
+ "META-INF/versions/9/module-info.class"));
+
+ // different version
+ mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
+ mie.mainClass("foo.main");
+ mie.version(Version.parse("2.0"));
+ baos.reset();
+ mie.write(baos);
+ Files.write(Paths.get("test6-v9", "module-info.class"), baos.toByteArray());
+
+ rc = jar("--create --file mmr.jar -C test6 . --release 9 -C test6-v9 .");
+ Assert.assertEquals(rc, 1);
+
+ Assert.assertTrue(Message.CONTAINS_DIFFERENT_VERSION.match(
+ new String(errbytes.toByteArray()),
+ "META-INF/versions/9/module-info.class"));
+
+ }
+
+ // versioned mmr without root module-info.class
+ @Test
+ public void test7() throws IOException {
+ // create a directory for this tests special files
+ Files.createDirectory(Paths.get("test7"));
+ Files.createDirectory(Paths.get("test7-v9"));
+ Files.createDirectory(Paths.get("test7-v10"));
+
+ // compile the classes directory
+ Path src = testsrc.resolve("src").resolve("classes");
+ Path dst = Paths.get("test7");
+ javac(src, dst);
+
+ // move module-info.class to v9 later use
+ Files.copy(Paths.get("module-info.class"),
+ Paths.get("test7-v9", "module-info.class"));
+
+ Files.copy(Paths.get("test7-v9", "module-info.class"),
+ Paths.get("test7-v10", "module-info.class"));
+
+ int rc = jar("--create --file mmr.jar --main-class=foo.main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
+
+System.out.println("-----------------------");
+System.out.println( new String(errbytes.toByteArray()));
+
+
+ Assert.assertEquals(rc, 0);
+
+
+ jar("-tf mmr.jar");
+
+System.out.println("-----------------------");
+System.out.println( new String(outbytes.toByteArray()));
+
+ Optional<String> exp = Optional.of("foo.main");
+ try (ZipFile zf = new ZipFile("mmr.jar")) {
+ Assert.assertTrue(zf.getEntry("module-info.class") == null);
+
+ ModuleDescriptor md = ModuleDescriptor.read(
+ zf.getInputStream(zf.getEntry("META-INF/versions/9/module-info.class")));
+ Assert.assertEquals(md.mainClass(), exp);
+
+ md = ModuleDescriptor.read(
+ zf.getInputStream(zf.getEntry("META-INF/versions/10/module-info.class")));
+ Assert.assertEquals(md.mainClass(), exp);
+ }
+ }
+
+ private static Set<String> lines(ByteArrayOutputStream baos) {
+ String s = new String(baos.toByteArray());
+ return Arrays.stream(s.split("\\R"))
+ .map(l -> l.trim())
+ .filter(l -> l.length() > 0)
+ .collect(Collectors.toSet());
+ }
+
+ static enum Message {
+ CONTAINS_DIFFERENT_MAINCLASS(
+ ": module-info.class in a versioned directory contains different \"main-class\""
+ ),
+ CONTAINS_DIFFERENT_VERSION(
+ ": module-info.class in a versioned directory contains different \"version\""
+ ),
+ NOT_FOUND_IN_BASE_ENTRY(
+ ", contains a new public class not found in base entries"
+ ),
+ NEW_CONCEALED_PACKAGE_WARNING(
+ " is a public class" +
+ " in a concealed package, placing this jar on the class path will result" +
+ " in incompatible public interfaces"
+ );
+
+ final String msg;
+ Message(String msg) {
+ this.msg = msg;
+ }
+
+ /*
+ * Test if the given output contains this message ignoring the line break.
+ */
+ boolean match(String output, String entry) {
+ System.out.println("Expected: " + entry + msg);
+ System.out.println("Found: " + output);
+ return Arrays.stream(output.split("\\R"))
+ .collect(Collectors.joining(" "))
+ .contains(entry + msg);
+ }
+ }
+}
--- a/jdk/test/tools/jar/mmrjar/ConcealedPackage.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-/*
- * 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 8146486
- * @summary Fail to create a MR modular JAR with a versioned entry in
- * base-versioned empty package
- * @modules jdk.compiler
- * jdk.jartool
- * @library /lib/testlibrary
- * @build jdk.testlibrary.FileUtils
- * @run testng ConcealedPackage
- */
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.spi.ToolProvider;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import jdk.testlibrary.FileUtils;
-
-public class ConcealedPackage {
- private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
- .orElseThrow(() -> new RuntimeException("jar tool not found"));
- private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac")
- .orElseThrow(() -> new RuntimeException("javac tool not found"));
- private final String linesep = System.lineSeparator();
- private final Path testsrc;
- private final Path userdir;
- private final ByteArrayOutputStream outbytes = new ByteArrayOutputStream();
- private final PrintStream out = new PrintStream(outbytes, true);
- private final ByteArrayOutputStream errbytes = new ByteArrayOutputStream();
- private final PrintStream err = new PrintStream(errbytes, true);
-
- public ConcealedPackage() throws IOException {
- testsrc = Paths.get(System.getProperty("test.src"));
- userdir = Paths.get(System.getProperty("user.dir", "."));
-
- // compile the classes directory
- Path source = testsrc.resolve("src").resolve("classes");
- Path destination = Paths.get("classes");
- javac(source, destination);
-
- // compile the mr9 directory including module-info.java
- source = testsrc.resolve("src").resolve("mr9");
- destination = Paths.get("mr9");
- javac(source, destination);
-
- // move module-info.class for later use
- Files.move(destination.resolve("module-info.class"),
- Paths.get("module-info.class"));
- }
-
- private void javac(Path source, Path destination) throws IOException {
- String[] args = Stream.concat(
- Stream.of("-d", destination.toString()),
- Files.walk(source)
- .map(Path::toString)
- .filter(s -> s.endsWith(".java"))
- ).toArray(String[]::new);
- JAVAC_TOOL.run(System.out, System.err, args);
- }
-
- private int jar(String cmd) {
- outbytes.reset();
- errbytes.reset();
- return JAR_TOOL.run(out, err, cmd.split(" +"));
- }
-
- @AfterClass
- public void cleanup() throws IOException {
- Files.walk(userdir, 1)
- .filter(p -> !p.equals(userdir))
- .forEach(p -> {
- try {
- if (Files.isDirectory(p)) {
- FileUtils.deleteFileTreeWithRetry(p);
- } else {
- FileUtils.deleteFileIfExistsWithRetry(p);
- }
- } catch (IOException x) {
- throw new UncheckedIOException(x);
- }
- });
- }
-
- // updates a valid multi-release jar with a new public class in
- // versioned section and fails
- @Test
- public void test1() {
- // successful build of multi-release jar
- int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
- Assert.assertEquals(rc, 0);
-
- jar("-tf mmr.jar");
-
- Set<String> actual = lines(outbytes);
- Set<String> expected = Set.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Hi.class",
- "META-INF/versions/9/p/Hi.class"
- );
- Assert.assertEquals(actual, expected);
-
- // failed build because of new public class
- rc = jar("-uf mmr.jar --release 9 -C mr9 p/internal/Bar.class");
- Assert.assertEquals(rc, 1);
-
- String s = new String(errbytes.toByteArray());
- Assert.assertTrue(Message.NOT_FOUND_IN_BASE_ENTRY.match(s, "p/internal/Bar.class"));
- }
-
- // updates a valid multi-release jar with a module-info class and new
- // concealed public class in versioned section and succeeds
- @Test
- public void test2() {
- // successful build of multi-release jar
- int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
- Assert.assertEquals(rc, 0);
-
- // successful build because of module-info and new public class
- rc = jar("-uf mmr.jar module-info.class --release 9 -C mr9 p/internal/Bar.class");
- Assert.assertEquals(rc, 0);
-
- String s = new String(errbytes.toByteArray());
- Assert.assertTrue(Message.NEW_CONCEALED_PACKAGE_WARNING.match(s, "p/internal/Bar.class"));
-
- jar("-tf mmr.jar");
-
- Set<String> actual = lines(outbytes);
- Set<String> expected = Set.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Hi.class",
- "META-INF/versions/9/p/Hi.class",
- "META-INF/versions/9/p/internal/Bar.class",
- "module-info.class"
- );
- Assert.assertEquals(actual, expected);
- }
-
- // jar tool fails building mmr.jar because of new public class
- @Test
- public void test3() {
- int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 .");
- Assert.assertEquals(rc, 1);
-
- String s = new String(errbytes.toByteArray());
- Assert.assertTrue(Message.NOT_FOUND_IN_BASE_ENTRY.match(s, "p/internal/Bar.class"));
- }
-
- // jar tool succeeds building mmr.jar because of concealed package
- @Test
- public void test4() {
- int rc = jar("-cf mmr.jar module-info.class -C classes . " +
- "--release 9 module-info.class -C mr9 .");
- Assert.assertEquals(rc, 0);
-
- String s = new String(errbytes.toByteArray());
- Assert.assertTrue(Message.NEW_CONCEALED_PACKAGE_WARNING.match(s, "p/internal/Bar.class"));
-
- jar("-tf mmr.jar");
-
- Set<String> actual = lines(outbytes);
- Set<String> expected = Set.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "module-info.class",
- "META-INF/versions/9/module-info.class",
- "p/",
- "p/Hi.class",
- "META-INF/versions/9/p/",
- "META-INF/versions/9/p/Hi.class",
- "META-INF/versions/9/p/internal/",
- "META-INF/versions/9/p/internal/Bar.class"
- );
- Assert.assertEquals(actual, expected);
- }
-
- // jar tool does two updates, no exported packages, all concealed
- @Test
- public void test5() throws IOException {
- // compile the mr10 directory
- Path source = testsrc.resolve("src").resolve("mr10");
- Path destination = Paths.get("mr10");
- javac(source, destination);
-
- // create a directory for this tests special files
- Files.createDirectory(Paths.get("test5"));
-
- // create an empty module-info.java
- String hi = "module hi {" + linesep + "}" + linesep;
- Path modinfo = Paths.get("test5", "module-info.java");
- Files.write(modinfo, hi.getBytes());
-
- // and compile it
- javac(modinfo, Paths.get("test5"));
-
- int rc = jar("--create --file mr.jar -C classes .");
- Assert.assertEquals(rc, 0);
-
- rc = jar("--update --file mr.jar -C test5 module-info.class"
- + " --release 9 -C mr9 .");
- Assert.assertEquals(rc, 0);
-
- jar("tf mr.jar");
-
- Set<String> actual = lines(outbytes);
- Set<String> expected = Set.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Hi.class",
- "META-INF/versions/9/p/",
- "META-INF/versions/9/p/Hi.class",
- "META-INF/versions/9/p/internal/",
- "META-INF/versions/9/p/internal/Bar.class",
- "module-info.class"
- );
- Assert.assertEquals(actual, expected);
-
- jar("-d --file mr.jar");
-
- actual = lines(outbytes);
- expected = Set.of(
- "hi",
- "requires mandated java.base",
- "contains p",
- "contains p.internal"
- );
- Assert.assertEquals(actual, expected);
-
- rc = jar("--update --file mr.jar --release 10 -C mr10 .");
- Assert.assertEquals(rc, 0);
-
- jar("tf mr.jar");
-
- actual = lines(outbytes);
- expected = Set.of(
- "META-INF/",
- "META-INF/MANIFEST.MF",
- "p/",
- "p/Hi.class",
- "META-INF/versions/9/p/",
- "META-INF/versions/9/p/Hi.class",
- "META-INF/versions/9/p/internal/",
- "META-INF/versions/9/p/internal/Bar.class",
- "META-INF/versions/10/p/",
- "META-INF/versions/10/p/internal/",
- "META-INF/versions/10/p/internal/bar/",
- "META-INF/versions/10/p/internal/bar/Gee.class",
- "module-info.class"
- );
- Assert.assertEquals(actual, expected);
-
- jar("-d --file mr.jar");
-
- actual = lines(outbytes);
- expected = Set.of(
- "hi",
- "requires mandated java.base",
- "contains p",
- "contains p.internal",
- "contains p.internal.bar"
- );
- Assert.assertEquals(actual, expected);
- }
-
- private static Set<String> lines(ByteArrayOutputStream baos) {
- String s = new String(baos.toByteArray());
- return Arrays.stream(s.split("\\R"))
- .map(l -> l.trim())
- .filter(l -> l.length() > 0)
- .collect(Collectors.toSet());
- }
-
- static enum Message {
- NOT_FOUND_IN_BASE_ENTRY(
- ", contains a new public class not found in base entries"
- ),
- NEW_CONCEALED_PACKAGE_WARNING(
- " is a public class" +
- " in a concealed package, placing this jar on the class path will result" +
- " in incompatible public interfaces"
- );
-
- final String msg;
- Message(String msg) {
- this.msg = msg;
- }
-
- /*
- * Test if the given output contains this message ignoring the line break.
- */
- boolean match(String output, String entry) {
- System.out.println("Expected: " + entry + msg);
- System.out.println("Found: " + output);
- return Arrays.stream(output.split("\\R"))
- .collect(Collectors.joining(" "))
- .contains(entry + msg);
- }
- }
-}
--- a/jdk/test/tools/jar/modularJar/Basic.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/tools/jar/modularJar/Basic.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -46,7 +46,7 @@
/*
* @test
- * @bug 8167328
+ * @bug 8167328 8171830
* @library /lib/testlibrary
* @modules jdk.compiler
* jdk.jartool
@@ -241,6 +241,11 @@
java(mp, FOO.moduleName + "/" + FOO.mainClass)
.assertSuccess()
+.resultChecker(r -> {
+ System.out.println("===================================");
+ System.out.println(r.output);
+ System.out.println("===================================");
+})
.resultChecker(r -> assertModuleData(r, FOO));
try (InputStream fis = Files.newInputStream(modularJar);
JarInputStream jis = new JarInputStream(fis)) {
@@ -417,6 +422,7 @@
jar("--update",
"--file=" + modularJar.toString(),
"--main-class=" + FOO.mainClass,
+ "--module-version=" + FOO.version,
"-m", mrjarDir.resolve("META-INF/MANIFEST.MF").toRealPath().toString(),
"-C", mrjarDir.toString(), "META-INF/versions/9/module-info.class")
.assertSuccess();
@@ -734,6 +740,25 @@
}
@Test
+ public void exportCreateWithMissingPkg() throws IOException {
+
+ Path foobar = TEST_SRC.resolve("src").resolve("foobar");
+ Path dst = Files.createDirectories(MODULE_CLASSES.resolve("foobar"));
+ javac(dst, null, sourceList(foobar));
+
+ Path mp = Paths.get("exportWithMissingPkg");
+ createTestDir(mp);
+ Path modClasses = dst;
+ Path modularJar = mp.resolve("foofoo.jar");
+
+ jar("--create",
+ "--file=" + modularJar.toString(),
+ "-C", modClasses.toString(), "module-info.class",
+ "-C", modClasses.toString(), "jdk/test/foo/Foo.class")
+ .assertFailure();
+ }
+
+ @Test
public void printModuleDescriptorFoo() throws IOException {
Path mp = Paths.get("printModuleDescriptorFoo");
createTestDir(mp);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/modularJar/src/foobar/Bar.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.bar;
+
+public class Bar {
+ public static void main(String[] args) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/modularJar/src/foobar/Foo.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.foo;
+
+public class Foo {
+ public static void main(String[] args) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/modularJar/src/foobar/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, 2017, 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.
+ */
+
+module foo {
+ exports jdk.test.foo;
+ exports jdk.test.bar;
+ opens jdk.test.foo;
+ opens jdk.test.bar;
+}
--- a/jdk/test/tools/jar/multiRelease/Basic1.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/tools/jar/multiRelease/Basic1.java Tue Jan 24 00:30:23 2017 +0100
@@ -62,15 +62,20 @@
Path source = Paths.get(src, "data", test, "base", "version");
javac(classes, source.resolve("Main.java"), source.resolve("Version.java"));
- Path v9 = Paths.get("v9").resolve("META-INF").resolve("versions").resolve("9");
+ Path v9 = Paths.get("v9");
Files.createDirectories(v9);
source = Paths.get(src, "data", test, "v9", "version");
javac(v9, source.resolve("Version.java"));
- Path v10 = Paths.get("v10").resolve("META-INF").resolve("versions").resolve("10");
+ Path v10 = Paths.get("v10");
Files.createDirectories(v10);
source = Paths.get(src, "data", test, "v10", "version");
javac(v10, source.resolve("Version.java"));
+
+ Path v10_1 = Paths.get("v10_1").resolve("META-INF").resolve("versions").resolve("v10");
+ Files.createDirectories(v10_1);
+ source = Paths.get(src, "data", test, "v10", "version");
+ javac(v10_1, source.resolve("Version.java"));
}
@Test
@@ -95,28 +100,30 @@
new String[] {"classes", "base", "version", "Version.class"},
"META-INF/versions/9/version/Version.class",
- new String[] {"v9", "META-INF", "versions", "9", "version", "Version.class"},
+ new String[] {"v9", "version", "Version.class"},
"META-INF/versions/10/version/Version.class",
- new String[] {"v10", "META-INF", "versions", "10", "version", "Version.class"}
+ new String[] {"v10", "version", "Version.class"}
);
compare(jarfile, names);
}
+
@Test
public void testFail() throws IOException {
String jarfile = "test.jar";
Path classes = Paths.get("classes");
- Path v9 = Paths.get("v9");
- Path v10 = Paths.get("v10");
+ Path v10 = Paths.get("v10_1");
jar("cf", jarfile, "-C", classes.resolve("base").toString(), ".",
- "--release", "9", "-C", v10.toString(), ".")
+ "--release", "10", "-C", v10.toString(), ".")
.assertFailure()
.outputContains("unexpected versioned entry META-INF/versions/");
}
+
+
private void checkMultiRelease(String jarFile, boolean expected) throws IOException {
try (JarFile jf = new JarFile(new File(jarFile), true, ZipFile.OPEN_READ,
JarFile.runtimeVersion())) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/RuntimeTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,236 @@
+/*
+ * 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
+ * @summary Test Multi-Release jar usage in runtime
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher
+ * jdk.test.lib.process.OutputAnalyzer
+ * jdk.test.lib.process.ProcessTools
+ * CompilerUtils RuntimeTest
+ * @run testng RuntimeTest
+ */
+
+import static org.testng.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class RuntimeTest {
+ public static final int SUCCESS = 0;
+ private final String src = System.getProperty("test.src", ".");
+ private final String usr = System.getProperty("user.dir", ".");
+
+ @DataProvider(name = "jarFiles")
+ Object[][] jarFiles() {
+ return new Object[][] { { "MV_BOTH.jar", 9, 9, 9 },
+ { "MV_ONLY_9.jar", 9, 9, 9 },
+ { "NON_MV.jar", 8, 8, 8 } };
+ }
+
+ @BeforeClass
+ protected void setUpTest() throws Throwable {
+ compile();
+ Path classes = Paths.get("classes");
+ jar("cfm", "MV_BOTH.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".",
+ "--release", "10", "-C", classes.resolve("v10").toString(), ".")
+ .shouldHaveExitValue(0);
+
+ jar("cfm", "MV_ONLY_9.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".")
+ .shouldHaveExitValue(0);
+ jar("cfm", "NON_MV.jar", "manifest.txt",
+ "-C", classes.resolve("base").toString(), ".")
+ .shouldHaveExitValue(0);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ public void testClasspath(String jar, int mainVer, int helperVer,
+ int resVer) throws Throwable {
+ String[] command = { "-cp", jar, "testpackage.Main" };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ String[] apps = { "UseByImport", "UseByReflection" };
+ for (String app : apps) {
+ String[] command = {"-cp",
+ jar + File.pathSeparatorChar + "classes/test/", app };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testJavaJar(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ String[] command = { "-jar", jar };
+ System.out.println("Command arguments:" + Arrays.asList(command));
+ System.out.println();
+ java(command).shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testURLClassLoader(String jarName, int mainVer, int helperVer,
+ int resVer) throws ClassNotFoundException, NoSuchMethodException,
+ IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, IOException {
+ Path pathToJAR = Paths.get(jarName).toAbsolutePath();
+ URL jarURL1 = new URL("jar:file:" + pathToJAR + "!/");
+ URL jarURL2 = new URL("file:///" + pathToJAR);
+ testURLClassLoaderURL(jarURL1, mainVer, helperVer, resVer);
+ testURLClassLoaderURL(jarURL2, mainVer, helperVer, resVer);
+ }
+
+ private static void testURLClassLoaderURL(URL jarURL,
+ int mainVersionExpected, int helperVersionExpected,
+ int resourceVersionExpected) throws ClassNotFoundException,
+ NoSuchMethodException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException, IOException {
+ System.out.println(
+ "Testing URLClassLoader MV JAR support for URL: " + jarURL);
+ URL[] urls = { jarURL };
+ int mainVersionActual;
+ int helperVersionActual;
+ int resourceVersionActual;
+ try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {
+ Class c = cl.loadClass("testpackage.Main");
+ Method getMainVersion = c.getMethod("getMainVersion");
+ mainVersionActual = (int) getMainVersion.invoke(null);
+ Method getHelperVersion = c.getMethod("getHelperVersion");
+ helperVersionActual = (int) getHelperVersion.invoke(null);
+ try (InputStream ris = cl.getResourceAsStream("versionResource");
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(ris))) {
+ resourceVersionActual = Integer.parseInt(br.readLine());
+ }
+ }
+
+ assertEquals(mainVersionActual, mainVersionExpected,
+ "Test failed: Expected Main class version: "
+ + mainVersionExpected + " Actual version: "
+ + mainVersionActual);
+ assertEquals(helperVersionActual, helperVersionExpected,
+ "Test failed: Expected Helper class version: "
+ + helperVersionExpected + " Actual version: "
+ + helperVersionActual);
+ assertEquals(resourceVersionActual, resourceVersionExpected,
+ "Test failed: Expected resource version: "
+ + resourceVersionExpected + " Actual version: "
+ + resourceVersionActual);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ void testJjs(String jar, int mainVer, int helperVer, int resVer)
+ throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jjs");
+ launcher.addToolArg("-cp").addToolArg(jar)
+ .addToolArg(src + "/data/runtimetest/MVJarJJSTestScript.js");
+ ProcessTools.executeCommand(launcher.getCommand())
+ .shouldHaveExitValue(SUCCESS)
+ .shouldContain("Main version: " + mainVer)
+ .shouldContain("Helpers version: " + helperVer)
+ .shouldContain("Resource version: " + resVer);
+ }
+
+ private static OutputAnalyzer jar(String... args) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");
+ Stream.of(args).forEach(launcher::addToolArg);
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ private void compile() throws Throwable {
+ String[] vers = { "base", "v9", "v10" };
+ for (String ver : vers) {
+ Path classes = Paths.get(usr, "classes", ver);
+ Files.createDirectories(classes);
+ Path source = Paths.get(src, "data", "runtimetest", ver);
+ assertTrue(CompilerUtils.compile(source, classes));
+ Files.copy(source.resolve("versionResource"),
+ classes.resolve("versionResource"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ Path classes = Paths.get(usr, "classes", "test");
+ Files.createDirectory(classes);
+ Path source = Paths.get(src, "data", "runtimetest", "test");
+ assertTrue(
+ CompilerUtils.compile(source, classes, "-cp", "classes/base/"));
+ Files.copy(Paths.get(src, "data", "runtimetest", "manifest.txt"),
+ Paths.get(usr, "manifest.txt"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ OutputAnalyzer java(String... args) throws Throwable {
+ String java = JDKToolFinder.getJDKTool("java");
+
+ List<String> commands = new ArrayList<>();
+ commands.add(java);
+ Stream.of(args).forEach(x -> commands.add(x));
+ return ProcessTools.executeCommand(new ProcessBuilder(commands));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/MVJarJJSTestScript.js Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+var Main = Java.type("testpackage.Main");
+var mainVersion = Main.getMainVersion();
+var helperVersion = Main.getHelperVersion();
+var resourceVersion = Main.getResourceVersion();
+print("Main version: " + mainVersion);
+print("Helpers version: " + helperVersion);
+print("Resource version: " + resourceVersion);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Helper.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 8;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Main.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 8;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/versionResource Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,1 @@
+8
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/manifest.txt Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,1 @@
+Main-Class: testpackage.Main
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByImport.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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 testpackage.Main;
+
+/**
+ * This class is used in MVJarAsLibraryTest.java test.
+ * It is a part of the test.
+ */
+public class UseByImport {
+
+ /**
+ * Method for the test execution.
+ * @param args - no args needed
+ */
+ public static void main(String[] args) {
+ System.out.println("Main version: " + Main.getMainVersion());
+ System.out.println("Helpers version: " + Main.getHelperVersion());
+ System.out.println("Resource version: " + Main.getResourceVersion());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByReflection.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,64 @@
+/*
+ * 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.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This class is used in RuntimeTest.java.
+ */
+public class UseByReflection {
+
+ /**
+ * Method for the test execution.
+ *
+ * @param args - no args needed
+ * @throws java.lang.ClassNotFoundException
+ * @throws java.lang.NoSuchMethodException
+ * @throws java.lang.IllegalAccessException
+ * @throws java.lang.reflect.InvocationTargetException
+ * @throws java.io.IOException
+ */
+ public static void main(String[] args) throws ClassNotFoundException,
+ NoSuchMethodException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException, IOException {
+ Class mainClass = Class.forName("testpackage.Main");
+ Method getMainVersion = mainClass.getMethod("getMainVersion");
+ int mainVersionActual = (int) getMainVersion.invoke(null);
+ Method getHelperVersion = mainClass.getMethod("getHelperVersion");
+ int helperVersionActual = (int) getHelperVersion.invoke(null);
+ ClassLoader cl = UseByReflection.class.getClassLoader();
+ int resourceVersionActual;
+ try (InputStream ris = cl.getResourceAsStream("versionResource");
+ BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ resourceVersionActual = Integer.parseInt(br.readLine());
+ }
+ System.out.println("Main version: " + mainVersionActual);
+ System.out.println("Helpers version: " + helperVersionActual);
+ System.out.println("Resource version: " + resourceVersionActual);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Helper.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 10;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Main.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 10;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/versionResource Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,1 @@
+10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Helper.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+public class Helper {
+
+ private static final int HELPER_VERSION = 9;
+
+ public static int getHelperVersion() {
+ return HELPER_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Main.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+ private static final int MAIN_VERSION = 9;
+
+ public static void main(String[] args) {
+ System.out.println("Main version: " + getMainVersion());
+ System.out.println("Helpers version: " + getHelperVersion());
+ System.out.println("Resource version: " + getResourceVersion());
+ }
+
+ public static int getMainVersion() {
+ return MAIN_VERSION;
+ }
+
+ public static int getHelperVersion() {
+ return testpackage.Helper.getHelperVersion();
+ }
+
+ public static int getResourceVersion() {
+ ClassLoader cl = Main.class.getClassLoader();
+ InputStream ris = cl.getResourceAsStream("versionResource");
+ if (ris == null) {
+ throw new Error("Test issue: resource versionResource"
+ + " cannot be loaded!");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+ return Integer.parseInt(br.readLine());
+ } catch (IOException ioe) {
+ throw new Error("Unexpected issue", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/versionResource Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,1 @@
+9
--- a/jdk/test/tools/jmod/JmodTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/tools/jmod/JmodTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8142968 8166568 8166286 8170618
+ * @bug 8142968 8166568 8166286 8170618 8168149
* @summary Basic test for jmod
* @library /lib/testlibrary
* @modules jdk.compiler
@@ -459,6 +459,76 @@
}
@Test
+ public void testLastOneWins() throws IOException {
+ Path workDir = Paths.get("lastOneWins");
+ if (Files.exists(workDir))
+ FileUtils.deleteFileTreeWithRetry(workDir);
+ Files.createDirectory(workDir);
+ Path jmod = MODS_DIR.resolve("lastOneWins.jmod");
+ FileUtils.deleteFileIfExistsWithRetry(jmod);
+ Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
+ Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
+ Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
+ Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");
+
+ Path shouldNotBeAdded = workDir.resolve("shouldNotBeAdded");
+ Files.createDirectory(shouldNotBeAdded);
+ Files.write(shouldNotBeAdded.resolve("aFile"), "hello".getBytes(UTF_8));
+
+ // Pairs of options. For options with required arguments the last one
+ // should win ( first should be effectively ignored, but may still be
+ // validated ).
+ jmod("create",
+ "--conf", shouldNotBeAdded.toString(),
+ "--conf", cf.toString(),
+ "--cmds", shouldNotBeAdded.toString(),
+ "--cmds", bp.toString(),
+ "--libs", shouldNotBeAdded.toString(),
+ "--libs", lp.toString(),
+ "--class-path", shouldNotBeAdded.toString(),
+ "--class-path", cp.toString(),
+ "--main-class", "does.NotExist",
+ "--main-class", "jdk.test.foo.Foo",
+ "--module-version", "00001",
+ "--module-version", "5.4.3",
+ "--do-not-resolve-by-default",
+ "--do-not-resolve-by-default",
+ "--warn-if-resolved=incubating",
+ "--warn-if-resolved=deprecated",
+ MODS_DIR.resolve("lastOneWins.jmod").toString())
+ .assertSuccess()
+ .resultChecker(r -> {
+ ModuleDescriptor md = getModuleDescriptor(jmod);
+ Optional<String> omc = md.mainClass();
+ assertTrue(omc.isPresent());
+ assertEquals(omc.get(), "jdk.test.foo.Foo");
+ Optional<Version> ov = md.version();
+ assertTrue(ov.isPresent());
+ assertEquals(ov.get().toString(), "5.4.3");
+
+ try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
+ Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p);
+ Stream<String> s3 = findFiles(bp).map(p -> CMDS_PREFIX + p);
+ Stream<String> s4 = findFiles(cf).map(p -> CONFIGS_PREFIX + p)) {
+ Set<String> expectedFilenames = Stream.concat(Stream.concat(s1,s2),
+ Stream.concat(s3, s4))
+ .collect(toSet());
+ assertJmodContent(jmod, expectedFilenames);
+ }
+ });
+
+ jmod("extract",
+ "--dir", "blah",
+ "--dir", "lastOneWinsExtractDir",
+ jmod.toString())
+ .assertSuccess()
+ .resultChecker(r -> {
+ assertTrue(Files.exists(Paths.get("lastOneWinsExtractDir")));
+ assertTrue(Files.notExists(Paths.get("blah")));
+ });
+ }
+
+ @Test
public void testPackagesAttribute() throws IOException {
Path jmod = MODS_DIR.resolve("foo.jmod");
FileUtils.deleteFileIfExistsWithRetry(jmod);
@@ -510,36 +580,24 @@
}
@Test
- public void testTmpFileAlreadyExists() throws IOException {
- // Implementation detail: jmod tool creates <jmod-file>.tmp
- // Ensure that there are no problems if existing
-
- Path jmod = MODS_DIR.resolve("testTmpFileAlreadyExists.jmod");
- Path tmp = MODS_DIR.resolve("testTmpFileAlreadyExists.jmod.tmp");
- FileUtils.deleteFileIfExistsWithRetry(jmod);
- FileUtils.deleteFileIfExistsWithRetry(tmp);
- Files.createFile(tmp);
- String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
-
- jmod("create",
- "--class-path", cp,
- jmod.toString())
- .assertSuccess()
- .resultChecker(r ->
- assertTrue(Files.notExists(tmp), "Unexpected tmp file:" + tmp)
- );
- }
-
- @Test
public void testTmpFileRemoved() throws IOException {
// Implementation detail: jmod tool creates <jmod-file>.tmp
// Ensure that it is removed in the event of a failure.
// The failure in this case is a class in the unnamed package.
- Path jmod = MODS_DIR.resolve("testTmpFileRemoved.jmod");
- Path tmp = MODS_DIR.resolve("testTmpFileRemoved.jmod.tmp");
+ String filename = "testTmpFileRemoved.jmod";
+ Path jmod = MODS_DIR.resolve(filename);
+
+ // clean up files
FileUtils.deleteFileIfExistsWithRetry(jmod);
- FileUtils.deleteFileIfExistsWithRetry(tmp);
+ findTmpFiles(filename).forEach(tmp -> {
+ try {
+ FileUtils.deleteFileIfExistsWithRetry(tmp);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
+
String cp = EXPLODED_DIR.resolve("foo").resolve("classes") + File.pathSeparator +
EXPLODED_DIR.resolve("foo").resolve("classes")
.resolve("jdk").resolve("test").resolve("foo").toString();
@@ -550,10 +608,22 @@
.assertFailure()
.resultChecker(r -> {
assertContains(r.output, "unnamed package");
- assertTrue(Files.notExists(tmp), "Unexpected tmp file:" + tmp);
+ Set<Path> tmpfiles = findTmpFiles(filename).collect(toSet());
+ assertTrue(tmpfiles.isEmpty(), "Unexpected tmp file:" + tmpfiles);
});
}
+ private Stream<Path> findTmpFiles(String prefix) {
+ try {
+ Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+ return Files.find(tmpdir, 1, (p, attrs) ->
+ p.getFileName().toString().startsWith(prefix)
+ && p.getFileName().toString().endsWith(".tmp"));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
// ---
static boolean compileModule(String name, Path dest) throws IOException {
--- a/jdk/test/tools/jmod/hashes/HashesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/jdk/test/tools/jmod/hashes/HashesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,19 +23,22 @@
/*
* @test
+ * @bug 8160286
* @summary Test the recording and checking of module hashes
- * @author Andrei Eremeev
* @library /lib/testlibrary
* @modules java.base/jdk.internal.misc
* java.base/jdk.internal.module
+ * jdk.compiler
+ * jdk.jartool
* jdk.jlink
- * jdk.compiler
- * @build CompilerUtils
+ * @build CompilerUtils ModuleInfoMaker
* @run testng HashesTest
*/
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
@@ -53,109 +56,311 @@
import java.util.Set;
import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import jdk.internal.module.ModuleInfo;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModulePath;
-import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
+import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
public class HashesTest {
static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
.orElseThrow(() ->
new RuntimeException("jmod tool not found")
);
+ static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+ .orElseThrow(() ->
+ new RuntimeException("jar tool not found")
+ );
- private final Path testSrc = Paths.get(System.getProperty("test.src"));
- private final Path modSrc = testSrc.resolve("src");
- private final Path mods = Paths.get("mods");
- private final Path jmods = Paths.get("jmods");
- private final String[] modules = new String[] { "m1", "m2", "m3"};
+ private final Path mods;
+ private final Path srcDir;
+ private final Path lib;
+ private final ModuleInfoMaker builder;
+ HashesTest(Path dest) throws IOException {
+ if (Files.exists(dest)) {
+ deleteDirectory(dest);
+ }
+ this.mods = dest.resolve("mods");
+ this.srcDir = dest.resolve("src");
+ this.lib = dest.resolve("lib");
+ this.builder = new ModuleInfoMaker(srcDir);
+
+ Files.createDirectories(lib);
+ Files.createDirectories(mods);
+ }
+
+ @Test
+ public static void test() throws IOException {
+ Path dest = Paths.get("test");
+ HashesTest ht = new HashesTest(dest);
- @BeforeTest
- private void setup() throws Exception {
- if (Files.exists(jmods)) {
- deleteDirectory(jmods);
- }
- Files.createDirectories(jmods);
+ // create modules for test cases
+ ht.makeModule("m2");
+ ht.makeModule("m3");
+ ht.makeModule("m1", "m2", "m3");
+
+ ht.makeModule("org.bar", TRANSITIVE, "m1");
+ ht.makeModule("org.foo", TRANSITIVE, "org.bar");
+
+ // create JMOD for m1, m2, m3
+ ht.makeJmod("m2");
+ ht.makeJmod("m3");
+
+ // no hash is recorded since m1 has outgoing edges
+ ht.jmodHashModules("m1", ".*");
+
+ // no hash is recorded in m1, m2, m3
+ assertTrue(ht.hashes("m1") == null);
+ assertTrue(ht.hashes("m2") == null);
+ assertTrue(ht.hashes("m3") == null);
+
+ // hash m1 in m2
+ ht.jmodHashModules("m2", "m1");
+ ht.checkHashes("m2", "m1");
+
+ // hash m1 in m2
+ ht.jmodHashModules("m2", ".*");
+ ht.checkHashes("m2", "m1");
- // build m2, m3 required by m1
- compileModule("m2", modSrc);
- jmod("m2");
+ // create m2.jmod with no hash
+ ht.makeJmod("m2");
+ // run jmod hash command to hash m1 in m2 and m3
+ runJmod(List.of("hash", "--module-path", ht.lib.toString(),
+ "--hash-modules", ".*"));
+ ht.checkHashes("m2", "m1");
+ ht.checkHashes("m3", "m1");
+
+ // check transitive requires
+ ht.makeJmod("org.bar");
+ ht.makeJmod("org.foo");
- compileModule("m3", modSrc);
- jmod("m3");
+ ht.jmodHashModules("org.bar", "org.*");
+ ht.checkHashes("org.bar", "org.foo");
+
+ ht.jmodHashModules( "m3", ".*");
+ ht.checkHashes("m3", "org.foo", "org.bar", "m1");
+ }
+
+ @Test
+ public static void multiBaseModules() throws IOException {
+ Path dest = Paths.get("test2");
+ HashesTest ht = new HashesTest(dest);
- // build m1
- compileModule("m1", modSrc);
- // no hash is recorded since m1 has outgoing edges
- jmod("m1", "--module-path", jmods.toString(), "--hash-modules", ".*");
+ /*
+ * y2 -----------> y1
+ * |______
+ * | |
+ * V V
+ * z3 -> z2
+ * | |
+ * | V
+ * |---> z1
+ */
+
+ ht.makeModule("z1");
+ ht.makeModule("z2", "z1");
+ ht.makeModule("z3", "z1", "z2");
+
+ ht.makeModule("y1");
+ ht.makeModule("y2", "y1", "z2", "z3");
- // compile org.bar and org.foo
- compileModule("org.bar", modSrc);
- compileModule("org.foo", modSrc);
+ Set<String> ys = Set.of("y1", "y2");
+ Set<String> zs = Set.of("z1", "z2", "z3");
+
+ // create JMOD files
+ Stream.concat(ys.stream(), zs.stream()).forEach(ht::makeJmod);
+
+ // run jmod hash command
+ runJmod(List.of("hash", "--module-path", ht.lib.toString(),
+ "--hash-modules", ".*"));
+
+ /*
+ * z1 and y1 are the modules with hashes recorded.
+ */
+ ht.checkHashes("y1", "y2");
+ ht.checkHashes("z1", "z2", "z3", "y2");
+ Stream.concat(ys.stream(), zs.stream())
+ .filter(mn -> !mn.equals("y1") && !mn.equals("z1"))
+ .forEach(mn -> assertTrue(ht.hashes(mn) == null));
}
@Test
- public void test() throws Exception {
- for (String mn : modules) {
- assertTrue(hashes(mn) == null);
+ public static void mixJmodAndJarFile() throws IOException {
+ Path dest = Paths.get("test3");
+ HashesTest ht = new HashesTest(dest);
+
+ /*
+ * j3 -----------> j2
+ * |______
+ * | |
+ * V V
+ * m3 -> m2
+ * | |
+ * | V
+ * |---> m1 -> j1 -> jdk.jlink
+ */
+
+ ht.makeModule("j1");
+ ht.makeModule("j2");
+ ht.makeModule("m1", "j1");
+ ht.makeModule("m2", "m1");
+ ht.makeModule("m3", "m1", "m2");
+
+ ht.makeModule("j3", "j2", "m2", "m3");
+
+ Set<String> jars = Set.of("j1", "j2", "j3");
+ Set<String> jmods = Set.of("m1", "m2", "m3");
+
+ // create JMOD and JAR files
+ jars.forEach(ht::makeJar);
+ jmods.forEach(ht::makeJmod);
+
+ // run jmod hash command
+ runJmod(List.of("hash", "--module-path", ht.lib.toString(),
+ "--hash-modules", "^j.*|^m.*"));
+
+ /*
+ * j1 and j2 are the modules with hashes recorded.
+ */
+ ht.checkHashes("j2", "j3");
+ ht.checkHashes("j1", "m1", "m2", "m3", "j3");
+ Stream.concat(jars.stream(), jmods.stream())
+ .filter(mn -> !mn.equals("j1") && !mn.equals("j2"))
+ .forEach(mn -> assertTrue(ht.hashes(mn) == null));
+ }
+
+ @Test
+ public static void upgradeableModule() throws IOException {
+ Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
+ if (!Files.exists(mpath)) {
+ return;
}
- // hash m1 in m2
- jmod("m2", "--module-path", jmods.toString(), "--hash-modules", "m1");
- checkHashes(hashes("m2"), "m1");
-
- // hash m1 in m2
- jmod("m2", "--module-path", jmods.toString(), "--hash-modules", ".*");
- checkHashes(hashes("m2"), "m1");
+ Path dest = Paths.get("test4");
+ HashesTest ht = new HashesTest(dest);
+ ht.makeModule("m1");
+ ht.makeModule("java.xml.bind", "m1");
+ ht.makeModule("java.xml.ws", "java.xml.bind");
+ ht.makeModule("m2", "java.xml.ws");
- // create m2.jmod with no hash
- jmod("m2");
- // run jmod hash command to hash m1 in m2 and m3
- runJmod(Arrays.asList("hash", "--module-path", jmods.toString(),
- "--hash-modules", ".*"));
- checkHashes(hashes("m2"), "m1");
- checkHashes(hashes("m3"), "m1");
+ ht.makeJmod("m1");
+ ht.makeJmod("m2");
+ ht.makeJmod("java.xml.ws");
+ ht.makeJmod("java.xml.bind",
+ "--module-path",
+ ht.lib.toString() + File.pathSeparator + mpath,
+ "--hash-modules", "^java.xml.*|^m.*");
- jmod("org.bar");
- jmod("org.foo");
-
- jmod("org.bar", "--module-path", jmods.toString(), "--hash-modules", "org.*");
- checkHashes(hashes("org.bar"), "org.foo");
-
- jmod("m3", "--module-path", jmods.toString(), "--hash-modules", ".*");
- checkHashes(hashes("m3"), "org.foo", "org.bar", "m1");
+ ht.checkHashes("java.xml.bind", "java.xml.ws", "m2");
}
- private void checkHashes(ModuleHashes hashes, String... hashModules) {
+ @Test
+ public static void testImageJmods() throws IOException {
+ Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
+ if (!Files.exists(mpath)) {
+ return;
+ }
+
+ Path dest = Paths.get("test5");
+ HashesTest ht = new HashesTest(dest);
+ ht.makeModule("m1", "jdk.compiler", "jdk.attach");
+ ht.makeModule("m2", "m1");
+ ht.makeModule("m3", "java.compiler");
+
+ ht.makeJmod("m1");
+ ht.makeJmod("m2");
+
+ runJmod(List.of("hash",
+ "--module-path",
+ mpath.toString() + File.pathSeparator + ht.lib.toString(),
+ "--hash-modules", ".*"));
+
+ validateImageJmodsTest(ht, mpath);
+ }
+
+ @Test
+ public static void testImageJmods1() throws IOException {
+ Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
+ if (!Files.exists(mpath)) {
+ return;
+ }
+
+ Path dest = Paths.get("test6");
+ HashesTest ht = new HashesTest(dest);
+ ht.makeModule("m1", "jdk.compiler", "jdk.attach");
+ ht.makeModule("m2", "m1");
+ ht.makeModule("m3", "java.compiler");
+
+ ht.makeJar("m2");
+ ht.makeJar("m1",
+ "--module-path",
+ mpath.toString() + File.pathSeparator + ht.lib.toString(),
+ "--hash-modules", ".*");
+ validateImageJmodsTest(ht, mpath);
+ }
+
+ private static void validateImageJmodsTest(HashesTest ht, Path mpath)
+ throws IOException
+ {
+ // hash is recorded in m1 and not any other packaged modules on module path
+ ht.checkHashes("m1", "m2");
+ assertTrue(ht.hashes("m2") == null);
+
+ // should not override any JDK packaged modules
+ ModuleFinder finder = new ModulePath(Runtime.version(),
+ true,
+ mpath);
+ assertTrue(ht.hashes(finder,"jdk.compiler") == null);
+ assertTrue(ht.hashes(finder,"jdk.attach") == null);
+ }
+
+ private void checkHashes(String mn, String... hashModules) throws IOException {
+ ModuleHashes hashes = hashes(mn);
assertTrue(hashes.names().equals(Set.of(hashModules)));
}
- private ModuleHashes hashes(String name) throws Exception {
+ private ModuleHashes hashes(String name) {
ModuleFinder finder = new ModulePath(Runtime.version(),
true,
- jmods.resolve(name + ".jmod"));
+ lib);
+ return hashes(finder, name);
+ }
+
+ private ModuleHashes hashes(ModuleFinder finder, String name) {
ModuleReference mref = finder.find(name).orElseThrow(RuntimeException::new);
- ModuleReader reader = mref.open();
- try (InputStream in = reader.open("module-info.class").get()) {
- ModuleHashes hashes = ModuleInfo.read(in, null).recordedHashes();
- System.out.format("hashes in module %s %s%n", name,
+ try {
+ ModuleReader reader = mref.open();
+ try (InputStream in = reader.open("module-info.class").get()) {
+ ModuleHashes hashes = ModuleInfo.read(in, null).recordedHashes();
+ System.out.format("hashes in module %s %s%n", name,
(hashes != null) ? "present" : "absent");
- if (hashes != null) {
- hashes.names().stream()
- .sorted()
- .forEach(n -> System.out.format(" %s %s%n", n, hashes.hashFor(n)));
+ if (hashes != null) {
+ hashes.names().stream().sorted().forEach(n ->
+ System.out.format(" %s %s%n", n, toHex(hashes.hashFor(n)))
+ );
+ }
+ return hashes;
+ } finally {
+ reader.close();
}
- return hashes;
- } finally {
- reader.close();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
+ private String toHex(byte[] ba) {
+ StringBuilder sb = new StringBuilder(ba.length);
+ for (byte b: ba) {
+ sb.append(String.format("%02x", b & 0xff));
+ }
+ return sb.toString();
+ }
+
private void deleteDirectory(Path dir) throws IOException {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
@@ -176,31 +381,94 @@
});
}
+
+ private void makeModule(String mn, String... deps) throws IOException {
+ makeModule(mn, null, deps);
+ }
+
+ private void makeModule(String mn, ModuleDescriptor.Requires.Modifier mod, String... deps)
+ throws IOException
+ {
+ if (mod != null && mod != TRANSITIVE && mod != STATIC) {
+ throw new IllegalArgumentException(mod.toString());
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("module " + mn + " {").append("\n");
+ Arrays.stream(deps).forEach(req -> {
+ sb.append(" requires ");
+ if (mod != null) {
+ sb.append(mod.toString().toLowerCase()).append(" ");
+ }
+ sb.append(req + ";\n");
+ });
+ sb.append("}\n");
+ builder.writeJavaFiles(mn, sb.toString());
+
+ compileModule(mn, srcDir);
+ }
+
private void compileModule(String moduleName, Path src) throws IOException {
Path msrc = src.resolve(moduleName);
assertTrue(CompilerUtils.compile(msrc, mods, "--module-source-path", src.toString()));
}
- private void jmod(String moduleName, String... options) throws IOException {
+ private void jmodHashModules(String moduleName, String hashModulesPattern) {
+ makeJmod(moduleName, "--module-path", lib.toString(),
+ "--hash-modules", hashModulesPattern);
+ }
+
+ private void makeJmod(String moduleName, String... options) {
Path mclasses = mods.resolve(moduleName);
- Path outfile = jmods.resolve(moduleName + ".jmod");
+ Path outfile = lib.resolve(moduleName + ".jmod");
List<String> args = new ArrayList<>();
args.add("create");
Collections.addAll(args, options);
Collections.addAll(args, "--class-path", mclasses.toString(),
outfile.toString());
- if (Files.exists(outfile))
- Files.delete(outfile);
-
+ if (Files.exists(outfile)) {
+ try {
+ Files.delete(outfile);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
runJmod(args);
}
- private void runJmod(List<String> args) {
+ private static void runJmod(List<String> args) {
int rc = JMOD_TOOL.run(System.out, System.out, args.toArray(new String[args.size()]));
- System.out.println("jmod options: " + args.stream().collect(Collectors.joining(" ")));
+ System.out.println("jmod " + args.stream().collect(Collectors.joining(" ")));
if (rc != 0) {
- throw new AssertionError("Jmod failed: rc = " + rc);
+ throw new AssertionError("jmod failed: rc = " + rc);
+ }
+ }
+
+ private void makeJar(String moduleName, String... options) {
+ Path mclasses = mods.resolve(moduleName);
+ Path outfile = lib.resolve(moduleName + ".jar");
+ List<String> args = new ArrayList<>();
+ Stream.concat(Stream.of("--create",
+ "--file=" + outfile.toString()),
+ Arrays.stream(options))
+ .forEach(args::add);
+ args.add("-C");
+ args.add(mclasses.toString());
+ args.add(".");
+
+ if (Files.exists(outfile)) {
+ try {
+ Files.delete(outfile);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ int rc = JAR_TOOL.run(System.out, System.out, args.toArray(new String[args.size()]));
+ System.out.println("jar " + args.stream().collect(Collectors.joining(" ")));
+ if (rc != 0) {
+ throw new AssertionError("jar failed: rc = " + rc);
}
}
}
--- a/jdk/test/tools/jmod/hashes/src/m1/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module m1 {
- requires m2;
- requires m3;
-}
--- a/jdk/test/tools/jmod/hashes/src/m1/org/m1/Main.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.m1;
-
-import org.m2.Util;
-import org.m3.Name;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println(Util.timeOfDay());
- System.out.println(Name.name());
- }
-}
--- a/jdk/test/tools/jmod/hashes/src/m2/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module m2 {
- exports org.m2;
-}
--- a/jdk/test/tools/jmod/hashes/src/m2/org/m2/Util.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.m2;
-
-public class Util {
- private Util() { }
-
- public static String timeOfDay() {
- return "Time for lunch";
- }
-}
--- a/jdk/test/tools/jmod/hashes/src/m3/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module m3 {
- exports org.m3;
-}
--- a/jdk/test/tools/jmod/hashes/src/m3/org/m3/Name.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.m3;
-
-public class Name {
- private Name() { }
-
- public static String name() {
- return "m3";
- }
-}
--- a/jdk/test/tools/jmod/hashes/src/org.bar/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-module org.bar {
- requires transitive m1;
-}
--- a/jdk/test/tools/jmod/hashes/src/org.foo/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-module org.foo {
- requires transitive org.bar;
-}
--- a/langtools/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -394,3 +394,5 @@
4d4cd7cd731c1952d7330ea5bcfda8bd26820fa5 jdk-9+149
e5a42ddaf633fde14b983f740ae0e7e490741fd1 jdk-9+150
4f348bd05341581df84ff1510d5b3a9b5b488367 jdk-9+151
+5b6f12de6f9167a582fa2c6ac54e69c591b09e68 jdk-9+152
+03f48cd283f5dd6b7153fd7e0cf2df8582b14391 jdk-9+153
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java Tue Jan 24 00:30:23 2017 +0100
@@ -243,9 +243,9 @@
* Returns the names of the annotation types supported by this
* processor. An element of the result may be the canonical
* (fully qualified) name of a supported annotation type.
- * Alternately it may be of the form "<tt><i>name</i>.*</tt>"
+ * Alternately it may be of the form "<code><i>name</i>.*</code>"
* representing the set of all annotation types with canonical
- * names beginning with "<tt><i>name.</i></tt>".
+ * names beginning with "<code><i>name.</i></code>".
*
* In either of those cases, the name of the annotation type can
* be optionally preceded by a module name followed by a {@code
@@ -267,13 +267,13 @@
* <dl>
* <dt><i>SupportedAnnotationTypeString:</i>
* <dd><i>ModulePrefix</i><sub><i>opt</i></sub> <i>TypeName</i> <i>DotStar</i><sub><i>opt</i></sub>
- * <dd><tt>*</tt>
+ * <dd><code>*</code>
*
* <dt><i>ModulePrefix:</i>
- * <dd><i>TypeName</i> <tt>/</tt>
+ * <dd><i>TypeName</i> <code>/</code>
*
* <dt><i>DotStar:</i>
- * <dd><tt>.</tt> <tt>*</tt>
+ * <dd><code>.</code> <code>*</code>
* </dl>
* </blockquote>
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -41,7 +41,7 @@
* implementing this interface are used to operate on a value when the
* type of that value is unknown at compile time. When a visitor is
* passed to a value's {@link AnnotationValue#accept accept} method,
- * the <tt>visit<i>XYZ</i></tt> method applicable to that value is
+ * the <code>visit<i>Xyz</i></code> method applicable to that value is
* invoked.
*
* <p> Classes implementing this interface may or may not throw a
@@ -65,9 +65,9 @@
* be added in a source <em>compatible</em> way if they were added as
* <em>default methods</em>. However, default methods are only
* available on Java SE 8 and higher releases and the {@code
- * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
- * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
* pattern. Classes implementing this interface are used to operate
* on an element when the kind of element is unknown at compile time.
* When a visitor is passed to an element's {@link Element#accept
- * accept} method, the <tt>visit<i>XYZ</i></tt> method most applicable
+ * accept} method, the <code>visit<i>Xyz</i></code> method most applicable
* to that element is invoked.
*
* <p> Classes implementing this interface may or may not throw a
@@ -56,9 +56,9 @@
* be added in a source <em>compatible</em> way if they were added as
* <em>default methods</em>. However, default methods are only
* available on Java SE 8 and higher releases and the {@code
- * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
- * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
* visitor design pattern. Classes implementing this
* interface are used to operate on a type when the kind of
* type is unknown at compile time. When a visitor is passed to a
- * type's {@link TypeMirror#accept accept} method, the <tt>visit<i>XYZ</i></tt>
+ * type's {@link TypeMirror#accept accept} method, the <code>visit<i>Xyz</i></code>
* method most applicable to that type is invoked.
*
* <p> Classes implementing this interface may or may not throw a
@@ -56,9 +56,9 @@
* be added in a source <em>compatible</em> way if they were added as
* <em>default methods</em>. However, default methods are only
* available on Java SE 8 and higher releases and the {@code
- * javax.lang.model.*} packages bundled in Java SE 8 are required to
+ * javax.lang.model.*} packages bundled in Java SE 8 were required to
* also be runnable on Java SE 7. Therefore, default methods
- * <em>cannot</em> be used when extending {@code javax.lang.model.*}
+ * were <em>not</em> used when extending {@code javax.lang.model.*}
* to cover Java SE 8 language features. However, default methods may
* be used in subsequent revisions of the {@code javax.lang.model.*}
* packages that are only required to run on Java SE 8 and higher
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/WildcardType.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/WildcardType.java Tue Jan 24 00:30:23 2017 +0100
@@ -28,11 +28,11 @@
/**
* Represents a wildcard type argument.
- * Examples include: <pre><tt>
+ * Examples include: <pre><code>
* ?
* ? extends Number
* ? super T
- * </tt></pre>
+ * </code></pre>
*
* <p> A wildcard may have its upper bound explicitly set by an
* {@code extends} clause, its lower bound explicitly set by a
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -54,15 +54,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -51,15 +51,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -51,15 +51,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -53,15 +53,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -36,10 +36,10 @@
* A visitor of program elements based on their {@linkplain
* ElementKind kind} with default behavior appropriate for the {@link
* SourceVersion#RELEASE_6 RELEASE_6} source version. For {@linkplain
- * Element elements} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * Element elements} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -67,15 +67,6 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of program elements based on their {@linkplain
* ElementKind kind} with default behavior appropriate for the {@link
* SourceVersion#RELEASE_7 RELEASE_7} source version. For {@linkplain
- * Element elements} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * Element elements} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -65,15 +65,6 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of program elements based on their {@linkplain
* ElementKind kind} with default behavior appropriate for the {@link
* SourceVersion#RELEASE_8 RELEASE_8} source version. For {@linkplain
- * Element elements} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * Element elements} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -65,15 +65,6 @@
* for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of program elements based on their {@linkplain
* ElementKind kind} with default behavior appropriate for the {@link
* SourceVersion#RELEASE_9 RELEASE_9} source version. For {@linkplain
- * Element elements} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * Element elements} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,26 +34,26 @@
/**
* A scanning visitor of program elements with default behavior
* appropriate for the {@link SourceVersion#RELEASE_6 RELEASE_6}
- * source version. The <tt>visit<i>XYZ</i></tt> methods in this
+ * source version. The <code>visit<i>Xyz</i></code> methods in this
* class scan their component elements by calling {@code scan} on
* their {@linkplain Element#getEnclosedElements enclosed elements},
* {@linkplain ExecutableElement#getParameters parameters}, etc., as
* indicated in the individual method specifications. A subclass can
* control the order elements are visited by overriding the
- * <tt>visit<i>XYZ</i></tt> methods. Note that clients of a scanner
+ * <code>visit<i>Xyz</i></code> methods. Note that clients of a scanner
* may get the desired behavior be invoking {@code v.scan(e, p)} rather
* than {@code v.visit(e, p)} on the root objects of interest.
*
- * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
+ * <p>When a subclass overrides a <code>visit<i>Xyz</i></code> method, the
* new method can cause the enclosed elements to be scanned in the
- * default way by calling <tt>super.visit<i>XYZ</i></tt>. In this
+ * default way by calling <code>super.visit<i>Xyz</i></code>. In this
* fashion, the concrete visitor can control the ordering of traversal
* over the component elements with respect to the additional
* processing; for example, consistently calling
- * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
+ * <code>super.visit<i>Xyz</i></code> at the start of the overridden
* methods will yield a preorder traversal, etc. If the component
* elements should be traversed in some other order, instead of
- * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
+ * calling <code>super.visit<i>Xyz</i></code>, an overriding visit method
* should call {@code scan} with the elements in the desired order.
*
* <p> Methods in this class may be overridden subject to their
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,26 +34,26 @@
/**
* A scanning visitor of program elements with default behavior
* appropriate for the {@link SourceVersion#RELEASE_7 RELEASE_7}
- * source version. The <tt>visit<i>XYZ</i></tt> methods in this
+ * source version. The <code>visit<i>Xyz</i></code> methods in this
* class scan their component elements by calling {@code scan} on
* their {@linkplain Element#getEnclosedElements enclosed elements},
* {@linkplain ExecutableElement#getParameters parameters}, etc., as
* indicated in the individual method specifications. A subclass can
* control the order elements are visited by overriding the
- * <tt>visit<i>XYZ</i></tt> methods. Note that clients of a scanner
+ * <code>visit<i>Xyz</i></code> methods. Note that clients of a scanner
* may get the desired behavior be invoking {@code v.scan(e, p)} rather
* than {@code v.visit(e, p)} on the root objects of interest.
*
- * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
+ * <p>When a subclass overrides a <code>visit<i>Xyz</i></code> method, the
* new method can cause the enclosed elements to be scanned in the
- * default way by calling <tt>super.visit<i>XYZ</i></tt>. In this
+ * default way by calling <code>super.visit<i>Xyz</i></code>. In this
* fashion, the concrete visitor can control the ordering of traversal
* over the component elements with respect to the additional
* processing; for example, consistently calling
- * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
+ * <code>super.visit<i>Xyz</i></code> at the start of the overridden
* methods will yield a preorder traversal, etc. If the component
* elements should be traversed in some other order, instead of
- * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
+ * calling <code>super.visit<i>Xyz</i></code>, an overriding visit method
* should call {@code scan} with the elements in the desired order.
*
* <p> Methods in this class may be overridden subject to their
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,26 +34,26 @@
/**
* A scanning visitor of program elements with default behavior
* appropriate for the {@link SourceVersion#RELEASE_8 RELEASE_8}
- * source version. The <tt>visit<i>XYZ</i></tt> methods in this
+ * source version. The <code>visit<i>Xyz</i></code> methods in this
* class scan their component elements by calling {@code scan} on
* their {@linkplain Element#getEnclosedElements enclosed elements},
* {@linkplain ExecutableElement#getParameters parameters}, etc., as
* indicated in the individual method specifications. A subclass can
* control the order elements are visited by overriding the
- * <tt>visit<i>XYZ</i></tt> methods. Note that clients of a scanner
+ * <code>visit<i>Xyz</i></code> methods. Note that clients of a scanner
* may get the desired behavior be invoking {@code v.scan(e, p)} rather
* than {@code v.visit(e, p)} on the root objects of interest.
*
- * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
+ * <p>When a subclass overrides a <code>visit<i>Xyz</i></code> method, the
* new method can cause the enclosed elements to be scanned in the
- * default way by calling <tt>super.visit<i>XYZ</i></tt>. In this
+ * default way by calling <code>super.visit<i>Xyz</i></code>. In this
* fashion, the concrete visitor can control the ordering of traversal
* over the component elements with respect to the additional
* processing; for example, consistently calling
- * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
+ * <code>super.visit<i>Xyz</i></code> at the start of the overridden
* methods will yield a preorder traversal, etc. If the component
* elements should be traversed in some other order, instead of
- * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
+ * calling <code>super.visit<i>Xyz</i></code>, an overriding visit method
* should call {@code scan} with the elements in the desired order.
*
* <p> Methods in this class may be overridden subject to their
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,26 +34,26 @@
/**
* A scanning visitor of program elements with default behavior
* appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9}
- * source version. The <tt>visit<i>XYZ</i></tt> methods in this
+ * source version. The <code>visit<i>Xyz</i></code> methods in this
* class scan their component elements by calling {@code scan} on
* their {@linkplain Element#getEnclosedElements enclosed elements},
* {@linkplain ExecutableElement#getParameters parameters}, etc., as
* indicated in the individual method specifications. A subclass can
* control the order elements are visited by overriding the
- * <tt>visit<i>XYZ</i></tt> methods. Note that clients of a scanner
+ * <code>visit<i>Xyz</i></code> methods. Note that clients of a scanner
* may get the desired behavior be invoking {@code v.scan(e, p)} rather
* than {@code v.visit(e, p)} on the root objects of interest.
*
- * <p>When a subclass overrides a <tt>visit<i>XYZ</i></tt> method, the
+ * <p>When a subclass overrides a <code>visit<i>Xyz</i></code> method, the
* new method can cause the enclosed elements to be scanned in the
- * default way by calling <tt>super.visit<i>XYZ</i></tt>. In this
+ * default way by calling <code>super.visit<i>Xyz</i></code>. In this
* fashion, the concrete visitor can control the ordering of traversal
* over the component elements with respect to the additional
* processing; for example, consistently calling
- * <tt>super.visit<i>XYZ</i></tt> at the start of the overridden
+ * <code>super.visit<i>Xyz</i></code> at the start of the overridden
* methods will yield a preorder traversal, etc. If the component
* elements should be traversed in some other order, instead of
- * calling <tt>super.visit<i>XYZ</i></tt>, an overriding visit method
+ * calling <code>super.visit<i>Xyz</i></code>, an overriding visit method
* should call {@code scan} with the elements in the desired order.
*
* <p> Methods in this class may be overridden subject to their
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -63,15 +63,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,15 +58,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,15 +58,6 @@
* behavior for the visit method in question. When the new visitor is
* introduced, all or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods
* @param <P> the type of the additional parameter to this visitor's methods.
*
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -65,15 +65,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -62,15 +62,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -61,15 +61,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@code Void}
* for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's methods. Use {@code Void}
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -64,15 +64,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -61,15 +61,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -61,15 +61,6 @@
* visit method in question. When the new visitor is introduced, all
* or portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of types based on their {@linkplain TypeKind kind} with
* default behavior appropriate for the {@link SourceVersion#RELEASE_6
* RELEASE_6} source version. For {@linkplain
- * TypeMirror types} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * TypeMirror types} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -63,15 +63,6 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of types based on their {@linkplain TypeKind kind} with
* default behavior appropriate for the {@link SourceVersion#RELEASE_7
* RELEASE_7} source version. For {@linkplain
- * TypeMirror types} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * TypeMirror types} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -63,15 +63,6 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor8.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor8.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of types based on their {@linkplain TypeKind kind} with
* default behavior appropriate for the {@link SourceVersion#RELEASE_8
* RELEASE_8} source version. For {@linkplain
- * TypeMirror types} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * TypeMirror types} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
@@ -63,15 +63,6 @@
* method in question. When the new visitor is introduced, all or
* portions of this visitor may be deprecated.
*
- * <p>Note that adding a default implementation of a new visit method
- * in a visitor class will occur instead of adding a <em>default
- * method</em> directly in the visitor interface since a Java SE 8
- * language feature cannot be used to this version of the API since
- * this version is required to be runnable on Java SE 7
- * implementations. Future versions of the API that are only required
- * to run on Java SE 8 and later may take advantage of default methods
- * in this situation.
- *
* @param <R> the return type of this visitor's methods. Use {@link
* Void} for visitors that do not need to return results.
* @param <P> the type of the additional parameter to this visitor's
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
* A visitor of types based on their {@linkplain TypeKind kind} with
* default behavior appropriate for the {@link SourceVersion#RELEASE_9
* RELEASE_9} source version. For {@linkplain
- * TypeMirror types} <tt><i>XYZ</i></tt> that may have more than one
- * kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
- * to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
- * first argument's kind. The <tt>visit<i>XYZKind</i></tt> methods
+ * TypeMirror types} <code><i>Xyz</i></code> that may have more than one
+ * kind, the <code>visit<i>Xyz</i></code> methods in this class delegate
+ * to the <code>visit<i>Xyz</i>As<i>Kind</i></code> method corresponding to the
+ * first argument's kind. The <code>visit<i>Xyz</i>As<i>Kind</i></code> methods
* call {@link #defaultAction defaultAction}, passing their arguments
* to {@code defaultAction}'s corresponding parameters.
*
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Jan 24 00:30:23 2017 +0100
@@ -921,6 +921,7 @@
public PackageSymbol unnamedPackage;
public Map<Name, PackageSymbol> visiblePackages;
+ public Set<ModuleSymbol> readModules;
public List<Symbol> enclosedPackages = List.nil();
public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Tue Jan 24 00:30:23 2017 +0100
@@ -61,7 +61,6 @@
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
-import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
@@ -469,9 +468,7 @@
scope.enter(errSymbol);
Source source = Source.instance(context);
- Options options = Options.instance(context);
- boolean noModules = options.isSet("noModules");
- if (source.allowModules() && !noModules) {
+ if (source.allowModules()) {
java_base = enterModule(names.java_base);
//avoid completing java.base during the Symtab initialization
java_base.completer = Completer.NULL_COMPLETER;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -47,6 +47,7 @@
import static com.sun.tools.javac.code.Flags.SYNTHETIC;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
+import static com.sun.tools.javac.code.Kinds.Kind.PCK;
import static com.sun.tools.javac.code.Kinds.Kind.VAR;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
@@ -228,7 +229,14 @@
s.resetAnnotations(); // mark Annotations as incomplete for now
normal(() -> {
- Assert.check(s.annotationsPendingCompletion());
+ // Packages are unusual, in that they are the only type of declaration that can legally appear
+ // more than once in a compilation, and in all cases refer to the same underlying symbol.
+ // This means they are the only kind of declaration that syntactically may have multiple sets
+ // of annotations, each on a different package declaration, even though that is ultimately
+ // forbidden by JLS 8 section 7.4.
+ // The corollary here is that all of the annotations on a package symbol may have already
+ // been handled, meaning that the set of annotations pending completion is now empty.
+ Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
DiagnosticPosition prevLintPos =
deferPos != null
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jan 24 00:30:23 2017 +0100
@@ -353,7 +353,7 @@
@Override @DefinedBy(Api.COMPILER_TREE)
public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) {
Symbol site = visit(node.getExpression(), env);
- if (site.kind == ERR || site.kind == ABSENT_TYP)
+ if (site.kind == ERR || site.kind == ABSENT_TYP || site.kind == HIDDEN)
return site;
Name name = (Name)node.getIdentifier();
if (site.kind == PCK) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -436,8 +436,10 @@
}
void clearLocalClassNameIndexes(ClassSymbol c) {
- localClassNameIndexes.remove(new Pair<>(
- c.owner.enclClass().flatname, c.name));
+ if (c.owner != null && c.owner.kind != NIL) {
+ localClassNameIndexes.remove(new Pair<>(
+ c.owner.enclClass().flatname, c.name));
+ }
}
public void newRound() {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Jan 24 00:30:23 2017 +0100
@@ -792,6 +792,7 @@
switch (tree.getTag()) {
case APPLY: ((JCMethodInvocation)tree).varargsElement = varargsElement; break;
case NEWCLASS: ((JCNewClass)tree).varargsElement = varargsElement; break;
+ case TYPECAST: setVarargsIfNeeded(((JCTypeCast) tree).expr, varargsElement); break;
default: throw new AssertionError();
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Tue Jan 24 00:30:23 2017 +0100
@@ -1327,6 +1327,7 @@
initAddExports();
msym.visiblePackages = new LinkedHashMap<>();
+ msym.readModules = new HashSet<>(readable);
Map<Name, ModuleSymbol> seen = new HashMap<>();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Jan 24 00:30:23 2017 +0100
@@ -54,14 +54,19 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
import java.util.function.BiPredicate;
+import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.lang.model.element.ElementVisitor;
+import com.sun.tools.javac.code.Directive.ExportsDirective;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK;
import static com.sun.tools.javac.code.Flags.STATIC;
@@ -69,6 +74,8 @@
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/** Helper class for name resolution, used mostly by the attribution phase.
@@ -89,6 +96,7 @@
Check chk;
Infer infer;
ClassFinder finder;
+ ModuleFinder moduleFinder;
Types types;
JCDiagnostic.Factory diags;
public final boolean allowMethodHandles;
@@ -98,8 +106,6 @@
private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
- private final boolean checkModuleAccess;
-
WriteableScope polymorphicSignatureScope;
protected Resolve(Context context) {
@@ -118,6 +124,7 @@
chk = Check.instance(context);
infer = Infer.instance(context);
finder = ClassFinder.instance(context);
+ moduleFinder = ModuleFinder.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
Source source = Source.instance(context);
@@ -135,10 +142,6 @@
inapplicableMethodException = new InapplicableMethodException(diags);
allowModules = source.allowModules();
-
- // The following is required, for now, to support building
- // Swing beaninfo via javadoc.
- checkModuleAccess = !options.isSet("noModules");
}
/** error symbols, which are returned when resolution fails
@@ -321,8 +324,7 @@
isAccessible = true;
break;
case PUBLIC:
- isAccessible = true;
- if (allowModules && checkModuleAccess) {
+ if (allowModules) {
ModuleSymbol currModule = env.toplevel.modle;
currModule.complete();
PackageSymbol p = c.packge();
@@ -497,7 +499,7 @@
public Void visitClassType(ClassType t, Env<AttrContext> env) {
visit(t.getTypeArguments(), env);
if (!isAccessible(env, t, true)) {
- accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
+ accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
}
return null;
}
@@ -1971,7 +1973,7 @@
Symbol loadClass(Env<AttrContext> env, Name name) {
try {
ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
- return isAccessible(env, c) ? c : new AccessError(c);
+ return isAccessible(env, c) ? c : new AccessError(env, null, c);
} catch (ClassFinder.BadClassFile err) {
throw err;
} catch (CompletionFailure ex) {
@@ -1989,20 +1991,29 @@
Symbol loadClass(Env<AttrContext> env, Name name);
}
- private RecoveryLoadClass recoveryLoadClass = (env, name) -> {
- //even if a class cannot be found in the current module and packages in modules it depends on that
- //are exported for any or this module, the class may exist internally in some of these modules,
- //or may exist in a module on which this module does not depend. Provide better diagnostic in
- //such cases by looking for the class in any module:
- for (ModuleSymbol ms : syms.getAllModules()) {
- //do not load currently unloaded classes, to avoid too eager completion of random things in other modules:
- ClassSymbol clazz = syms.getClass(ms, name);
-
- if (clazz != null) {
- return new AccessError(clazz);
+ private RecoveryLoadClass recoveryLoadClass = new RecoveryLoadClass() {
+ @Override
+ public Symbol loadClass(Env<AttrContext> env, Name name) {
+ if (allowModules) {
+ Scope importScope = env.toplevel.namedImportScope;
+ Symbol existing = importScope.findFirst(Convert.shortName(name),
+ sym -> sym.kind == TYP && sym.flatName() == name);
+
+ if (existing != null) {
+ return new InvisibleSymbolError(env, true, existing);
+ }
+
+ return lookupInvisibleSymbol(env, name, syms::getClass, (ms, n) -> {
+ try {
+ return finder.loadClass(ms, n);
+ } catch (CompletionFailure cf) {
+ //ignore
+ return null;
+ }
+ }, sym -> sym.kind == Kind.TYP, false, typeNotFound);
}
- }
- return null;
+ return null;
+ }
};
public RecoveryLoadClass setRecoveryLoadClass(RecoveryLoadClass recovery) {
@@ -2011,6 +2022,84 @@
return prev;
}
+ Symbol lookupPackage(Env<AttrContext> env, Name name) {
+ PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
+
+ if (allowModules && isImportOnDemand(env, name)) {
+ pack.complete();
+ if (!pack.exists()) {
+ Name nameAndDot = name.append('.', names.empty);
+ boolean prefixOfKnown =
+ env.toplevel.modle.visiblePackages.values()
+ .stream()
+ .anyMatch(p -> p.fullname.startsWith(nameAndDot));
+
+ return lookupInvisibleSymbol(env, name, syms::getPackage, syms::enterPackage, sym -> {
+ sym.complete();
+ return sym.exists();
+ }, prefixOfKnown, pack);
+ }
+ }
+
+ return pack;
+ }
+
+ private boolean isImportOnDemand(Env<AttrContext> env, Name name) {
+ if (!env.tree.hasTag(IMPORT))
+ return false;
+
+ JCTree qualid = ((JCImport) env.tree).qualid;
+
+ if (!qualid.hasTag(SELECT))
+ return false;
+
+ if (TreeInfo.name(qualid) != names.asterisk)
+ return false;
+
+ return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
+ }
+
+ private Symbol lookupInvisibleSymbol(Env<AttrContext> env,
+ Name name,
+ BiFunction<ModuleSymbol, Name, Symbol> get,
+ BiFunction<ModuleSymbol, Name, Symbol> load,
+ Predicate<Symbol> validate,
+ boolean suppressError,
+ Symbol defaultResult) {
+ //even if a class/package cannot be found in the current module and among packages in modules
+ //it depends on that are exported for any or this module, the class/package may exist internally
+ //in some of these modules, or may exist in a module on which this module does not depend.
+ //Provide better diagnostic in such cases by looking for the class in any module:
+ Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
+
+ recoverableModules.remove(env.toplevel.modle);
+
+ for (ModuleSymbol ms : recoverableModules) {
+ Symbol sym = get.apply(ms, name);
+
+ //avoid overly eager completing classes from source-based modules, as those
+ //may not be completable with the current compiler settings:
+ if (sym == null && (ms.sourceLocation == null)) {
+ if (ms.classLocation == null) {
+ ms = moduleFinder.findModule(ms);
+ }
+
+ if (ms.kind != ERR) {
+ sym = load.apply(ms, name);
+ }
+ }
+
+ if (sym == null)
+ continue;
+
+ if (validate.test(sym)) {
+ return new InvisibleSymbolError(env, suppressError, sym);
+ }
+ }
+
+ return defaultResult;
+ }
+
/**
* Find a type declared in a scope (not inherited). Return null
* if none is found.
@@ -2211,7 +2300,7 @@
}
if (kind.contains(KindSelector.PCK))
- return syms.lookupPackage(env.toplevel.modle, name);
+ return lookupPackage(env, name);
else return bestSoFar;
}
@@ -2225,11 +2314,6 @@
Name name, KindSelector kind) {
Name fullname = TypeSymbol.formFullName(name, pck);
Symbol bestSoFar = typeNotFound;
- PackageSymbol pack = null;
- if (kind.contains(KindSelector.PCK)) {
- pack = syms.lookupPackage(env.toplevel.modle, fullname);
- if (pack.exists()) return pack;
- }
if (kind.contains(KindSelector.TYP)) {
Symbol sym = loadClass(env, fullname);
if (sym.exists()) {
@@ -2238,7 +2322,10 @@
}
else bestSoFar = bestOf(bestSoFar, sym);
}
- return (pack != null) ? pack : bestSoFar;
+ if (kind.contains(KindSelector.PCK)) {
+ return lookupPackage(env, fullname);
+ }
+ return bestSoFar;
}
/** Find an identifier among the members of a given type `site'.
@@ -3947,10 +4034,6 @@
private Env<AttrContext> env;
private Type site;
- AccessError(Symbol sym) {
- this(null, null, sym);
- }
-
AccessError(Env<AttrContext> env, Type site, Symbol sym) {
super(HIDDEN, sym, "access error");
this.env = env;
@@ -3983,7 +4066,14 @@
if (sym.owner.kind == PCK) {
return diags.create(dkind, log.currentSource(),
pos, "not.def.access.package.cant.access",
- sym, sym.location());
+ sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
+ } else if ( sym.packge() != syms.rootPackage
+ && sym.packge().modle != env.toplevel.modle
+ && !isAccessible(env, sym.outermostClass())) {
+ return diags.create(dkind, log.currentSource(),
+ pos, "not.def.access.class.intf.cant.access.reason",
+ sym, sym.location(), sym.location().packge(),
+ inaccessiblePackageReason(env, sym.packge()));
} else {
return diags.create(dkind, log.currentSource(),
pos, "not.def.access.class.intf.cant.access",
@@ -4015,6 +4105,90 @@
}
}
+ class InvisibleSymbolError extends InvalidSymbolError {
+
+ private final Env<AttrContext> env;
+ private final boolean suppressError;
+
+ InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
+ super(HIDDEN, sym, "invisible class error");
+ this.env = env;
+ this.suppressError = suppressError;
+ this.name = sym.name;
+ }
+
+ @Override
+ JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+ DiagnosticPosition pos,
+ Symbol location,
+ Type site,
+ Name name,
+ List<Type> argtypes,
+ List<Type> typeargtypes) {
+ if (suppressError)
+ return null;
+
+ if (sym.kind == PCK) {
+ JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
+ return diags.create(dkind, log.currentSource(),
+ pos, "package.not.visible", sym, details);
+ }
+
+ JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
+
+ if (pos.getTree() != null && pos.getTree().hasTag(SELECT) && sym.owner.kind == PCK) {
+ pos = ((JCFieldAccess) pos.getTree()).selected.pos();
+
+ return diags.create(dkind, log.currentSource(),
+ pos, "package.not.visible", sym.packge(), details);
+ }
+
+ return diags.create(dkind, log.currentSource(),
+ pos, "not.def.access.package.cant.access", sym, sym.packge(), details);
+ }
+ }
+
+ JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) {
+ //no dependency:
+ if (!env.toplevel.modle.readModules.contains(sym.modle)) {
+ //does not read:
+ if (sym.modle != syms.unnamedModule) {
+ if (env.toplevel.modle != syms.unnamedModule) {
+ return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle,
+ sym,
+ sym.modle));
+ } else {
+ return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym,
+ sym.modle));
+ }
+ } else {
+ return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym,
+ env.toplevel.modle));
+ }
+ } else {
+ if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) {
+ //not exported to this module:
+ if (env.toplevel.modle != syms.unnamedModule) {
+ return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym,
+ sym.modle,
+ env.toplevel.modle));
+ } else {
+ return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym,
+ sym.modle));
+ }
+ } else {
+ //not exported:
+ if (env.toplevel.modle != syms.unnamedModule) {
+ return diags.fragment(Fragments.NotDefAccessNotExported(sym,
+ sym.modle));
+ } else {
+ return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym,
+ sym.modle));
+ }
+ }
+ }
+ }
+
/**
* InvalidSymbolError error class indicating that an instance member
* has erroneously been accessed from a static context.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -410,7 +410,9 @@
importNamedStatic(tree, p, name, localEnv);
chk.checkCanonical(imp.selected);
} else {
- TypeSymbol c = attribImportType(imp, localEnv).tsym;
+ Type importedType = attribImportType(imp, localEnv);
+ Type originalType = importedType.getOriginalType();
+ TypeSymbol c = originalType.hasTag(CLASS) ? originalType.tsym : importedType.tsym;
chk.checkCanonical(imp);
importNamed(tree.pos(), c, env, tree);
}
@@ -938,6 +940,7 @@
*/
void finishClass(JCClassDecl tree, Env<AttrContext> env) {
if ((tree.mods.flags & Flags.ENUM) != 0 &&
+ !tree.sym.type.hasTag(ERROR) &&
(types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
addEnumMembers(tree, env);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -818,13 +818,17 @@
return List.nil();
String checkPackages = options.get(Option.XDOCLINT_PACKAGE);
-
if (checkPackages != null) {
for (String s : checkPackages.split("\\s+")) {
doclintOpts.add(DocLint.XCHECK_PACKAGE + s);
}
}
+ String format = options.get(Option.DOCLINT_FORMAT);
+ if (format != null) {
+ doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + format);
+ }
+
// standard doclet normally generates H1, H2,
// so for now, allow user comments to assume that
doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Jan 24 00:30:23 2017 +0100
@@ -681,7 +681,7 @@
if (sep == -1) {
msym = modules.getDefaultModule();
typeName = name;
- } else if (source.allowModules() && !options.isSet("noModules")) {
+ } else if (source.allowModules()) {
Name modName = names.fromString(name.substring(0, sep));
msym = moduleFinder.findModule(modName);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -154,6 +154,8 @@
}
},
+ DOCLINT_FORMAT("--doclint-format", "opt.doclint.format", EXTENDED, BASIC, ONEOF, "html4", "html5"),
+
// -nowarn is retained for command-line backward compatibility
NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
@Override
@@ -1216,10 +1218,12 @@
sb.append(name);
if (argsNameKey == null) {
if (choices != null) {
+ if (!name.endsWith(":"))
+ sb.append(" ");
String sep = "{";
for (String choice : choices) {
sb.append(sep);
- sb.append(choices);
+ sb.append(choice);
sep = ",";
}
sb.append("}");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,11 @@
package com.sun.tools.javac.model;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.lang.model.AnnotatedConstruct;
import javax.lang.model.SourceVersion;
@@ -67,6 +69,7 @@
import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.comp.Resolve.RecoveryLoadClass;
+import com.sun.tools.javac.resources.CompilerProperties.Notes;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/**
@@ -87,6 +90,8 @@
private final Enter enter;
private final Resolve resolve;
private final JavacTaskImpl javacTaskImpl;
+ private final Log log;
+ private final boolean allowModules;
public static JavacElements instance(Context context) {
JavacElements instance = context.get(JavacElements.class);
@@ -106,6 +111,9 @@
resolve = Resolve.instance(context);
JavacTask t = context.get(JavacTask.class);
javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null;
+ log = Log.instance(context);
+ Source source = Source.instance(context);
+ allowModules = source.allowModules();
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
@@ -134,7 +142,7 @@
ensureEntered("getPackageElement");
if (name.length() == 0)
return syms.unnamedModule.unnamedPackage;
- return doGetElement(module, name, PackageSymbol.class);
+ return doGetElement(module, "getPackageElement", name, PackageSymbol.class);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
@@ -151,22 +159,27 @@
private ClassSymbol doGetTypeElement(ModuleElement module, CharSequence name) {
ensureEntered("getTypeElement");
- return doGetElement(module, name, ClassSymbol.class);
+ return doGetElement(module, "getTypeElement", name, ClassSymbol.class);
}
- private <S extends Symbol> S doGetElement(ModuleElement module, CharSequence name, Class<S> clazz) {
+ private <S extends Symbol> S doGetElement(ModuleElement module, String methodName,
+ CharSequence name, Class<S> clazz) {
String strName = name.toString();
if (!SourceVersion.isName(strName)) {
return null;
}
if (module == null) {
- return unboundNameToSymbol(strName, clazz);
+ return unboundNameToSymbol(methodName, strName, clazz);
} else {
return nameToSymbol((ModuleSymbol) module, strName, clazz);
}
}
- private <S extends Symbol> S unboundNameToSymbol(String nameStr, Class<S> clazz) {
+ private final Set<String> alreadyWarnedDuplicates = new HashSet<>();
+
+ private <S extends Symbol> S unboundNameToSymbol(String methodName,
+ String nameStr,
+ Class<S> clazz) {
if (modules.getDefaultModule() == syms.noModule) { //not a modular mode:
return nameToSymbol(syms.noModule, nameStr, clazz);
}
@@ -179,12 +192,25 @@
S sym = nameToSymbol(msym, nameStr, clazz);
if (sym != null) {
- found.add(sym);
+ if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
+ //do not add packages without members:
+ found.add(sym);
+ }
}
}
if (found.size() == 1) {
return found.iterator().next();
+ } else if (found.size() > 1) {
+ //more than one element found, produce a note:
+ if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
+ String moduleNames = found.stream()
+ .map(s -> s.packge().modle)
+ .map(m -> m.toString())
+ .collect(Collectors.joining(", "));
+ log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
+ }
+ return null;
} else {
//not found, or more than one element found:
return null;
@@ -222,41 +248,6 @@
}
}
- public JavacSourcePosition getSourcePosition(Element e) {
- Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e);
- if (treeTop == null)
- return null;
- JCTree tree = treeTop.fst;
- JCCompilationUnit toplevel = treeTop.snd;
- JavaFileObject sourcefile = toplevel.sourcefile;
- if (sourcefile == null)
- return null;
- return new JavacSourcePosition(sourcefile, tree.pos, toplevel.lineMap);
- }
-
- public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a) {
- Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e);
- if (treeTop == null)
- return null;
- JCTree tree = treeTop.fst;
- JCCompilationUnit toplevel = treeTop.snd;
- JavaFileObject sourcefile = toplevel.sourcefile;
- if (sourcefile == null)
- return null;
-
- JCTree annoTree = matchAnnoToTree(a, e, tree);
- if (annoTree == null)
- return null;
- return new JavacSourcePosition(sourcefile, annoTree.pos,
- toplevel.lineMap);
- }
-
- public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a,
- AnnotationValue v) {
- // TODO: better accuracy in getSourcePosition(... AnnotationValue)
- return getSourcePosition(e, a);
- }
-
/**
* Returns the tree for an annotation given the annotated element
* and the element's own tree. Returns null if the tree cannot be found.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacSourcePosition.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005, 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 com.sun.tools.javac.model;
-
-import javax.tools.JavaFileObject;
-import com.sun.tools.javac.util.Position;
-
-/**
- * Implementation of model API SourcePosition based on javac internal state.
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-class JavacSourcePosition {
-
- final JavaFileObject sourcefile;
- final int pos;
- final Position.LineMap lineMap;
-
- JavacSourcePosition(JavaFileObject sourcefile,
- int pos,
- Position.LineMap lineMap) {
- this.sourcefile = sourcefile;
- this.pos = pos;
- this.lineMap = (pos != Position.NOPOS) ? lineMap : null;
- }
-
- public JavaFileObject getFile() {
- return sourcefile;
- }
-
- public int getOffset() {
- return pos; // makes use of fact that Position.NOPOS == -1
- }
-
- public int getLine() {
- return (lineMap != null) ? lineMap.getLineNumber(pos) : -1;
- }
-
- public int getColumn() {
- return (lineMap != null) ? lineMap.getColumnNumber(pos) : -1;
- }
-
- public String toString() {
- int line = getLine();
- return (line > 0)
- ? sourcefile + ":" + line
- : sourcefile.toString();
- }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Jan 24 00:30:23 2017 +0100
@@ -230,7 +230,7 @@
chk = Check.instance(context);
initProcessorLoader();
- allowModules = source.allowModules() && options.isUnset("noModules");
+ allowModules = source.allowModules();
}
public void setProcessors(Iterable<? extends Processor> processors) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2017, 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
@@ -823,17 +823,87 @@
compiler.err.not.annotation.type=\
{0} is not an annotation type
-# 0: symbol, 1: symbol
+# 0: symbol, 1: symbol, 2: message segment
compiler.err.not.def.access.package.cant.access=\
- {0} is not visible because package {1} is not visible
+ {0} is not visible\n\
+ ({2})
+
+# 0: symbol, 1: symbol, 2: message segment
+compiler.misc.not.def.access.package.cant.access=\
+ {0} is not visible\n\
+ ({2})
+
+# 0: symbol, 1: message segment
+compiler.err.package.not.visible=\
+ package {0} is not visible\n\
+ ({1})
+
+# 0: symbol, 1: message segment
+compiler.misc.package.not.visible=\
+ package {0} is not visible\n\
+ ({1})
+
+# {0} - current module
+# {1} - package in which the invisible class is declared
+# {2} - module in which {1} is declared
+# 0: symbol, 1: symbol, 2: symbol
+compiler.misc.not.def.access.does.not.read=\
+ package {1} is declared in module {2}, but module {0} does not read it
+
+# {0} - package in which the invisible class is declared
+# {1} - module in which {0} is declared
+# 0: symbol, 1: symbol
+compiler.misc.not.def.access.does.not.read.from.unnamed=\
+ package {0} is declared in module {1}, which is not in the module graph
+
+# {0} - package in which the invisible class is declared
+# {1} - current module
+# 0: symbol, 1: symbol
+compiler.misc.not.def.access.does.not.read.unnamed=\
+ package {0} is declared in the unnamed module, but module {0} does not read it
+
+# {0} - package in which the invisible class is declared
+# {1} - module in which {0} is declared
+# 0: symbol, 1: symbol
+compiler.misc.not.def.access.not.exported=\
+ package {0} is declared in module {1}, which does not export it
+
+# {0} - package in which the invisible class is declared
+# {1} - module in which {0} is declared
+# 0: symbol, 1: symbol
+compiler.misc.not.def.access.not.exported.from.unnamed=\
+ package {0} is declared in module {1}, which does not export it
+
+# {0} - package in which the invisible class is declared
+# {1} - module in which {0} is declared
+# {2} - current module
+# 0: symbol, 1: symbol, 2: symbol
+compiler.misc.not.def.access.not.exported.to.module=\
+ package {0} is declared in module {1}, which does not export it to module {2}
+
+# {0} - package in which the invisible class is declared
+# {1} - module in which {0} is declared
+# 0: symbol, 1: symbol
+compiler.misc.not.def.access.not.exported.to.module.from.unnamed=\
+ package {0} is declared in module {1}, which does not export it to the unnamed module
# 0: symbol, 1: symbol
compiler.err.not.def.access.class.intf.cant.access=\
- {0} in {1} is defined in an inaccessible class or interface
+ {1}.{0} is defined in an inaccessible class or interface
# 0: symbol, 1: symbol
compiler.misc.not.def.access.class.intf.cant.access=\
- {0} in {1} is defined in an inaccessible class or interface
+ {1}.{0} is defined in an inaccessible class or interface
+
+# 0: symbol, 1: symbol, 2: symbol, 3: message segment
+compiler.err.not.def.access.class.intf.cant.access.reason=\
+ {1}.{0} in package {2} is not accessible\n\
+ ({3})
+
+# 0: symbol, 1: symbol, 2: symbol, 3: message segment
+compiler.misc.not.def.access.class.intf.cant.access.reason=\
+ {1}.{0} in package {2} is not accessible\n\
+ ({3})
# 0: symbol, 1: list of type, 2: type
compiler.misc.cant.access.inner.cls.constr=\
@@ -1366,6 +1436,10 @@
compiler.note.proc.messager=\
{0}
+# 0: string, 1: string, 2: string
+compiler.note.multiple.elements=\
+ Multiple elements named '{1}' in modules '{2}' were found by javax.lang.model.util.Elements.{0}.
+
#####
# 0: number
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2017, 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
@@ -263,6 +263,9 @@
expands to all sub-packages of the given package. Each <package> can be prefixed\n\
with '-' to disable checks for the specified package or packages.
+javac.opt.doclint.format=\
+ Specify the format for documentation comments
+
javac.opt.Xstdout=\
Redirect standard output
javac.opt.X=\
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Tue Jan 24 00:30:23 2017 +0100
@@ -68,6 +68,11 @@
*/
public static final int DBG_EVNT = 0b0010000;
+ /**
+ * Event debugging.
+ */
+ public static final int DBG_WRAP = 0b0100000;
+
private static Map<JShell, Integer> debugMap = null;
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Tue Jan 24 00:30:23 2017 +0100
@@ -119,6 +119,7 @@
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_FMGR;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_WRAP;
import static jdk.internal.jshell.tool.ContinuousCompletionProvider.STARTSWITH_MATCHER;
/**
@@ -217,7 +218,7 @@
static final String DEFAULT_STARTUP_NAME = "DEFAULT";
static final Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+");
- static final String BUILTIN_FILE_PATH_FORMAT = "jrt:/jdk.jshell/jdk/jshell/tool/resources/%s.jsh";
+ static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh";
// match anything followed by whitespace
private static final Pattern OPTION_PRE_PATTERN =
@@ -1919,9 +1920,13 @@
flags |= DBG_EVNT;
fluff("Event debugging on");
break;
+ case 'w':
+ flags |= DBG_WRAP;
+ fluff("Wrap debugging on");
+ break;
default:
hard("Unknown debugging option: %c", ch);
- fluff("Use: 0 r g f c d");
+ fluff("Use: 0 r g f c d e w");
return false;
}
}
@@ -2421,9 +2426,11 @@
String readResource(String name) throws IOException {
// Attempt to find the file as a resource
String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name);
- URL url = new URL(spec);
- BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
- return reader.lines().collect(Collectors.joining("\n"));
+
+ try (InputStream in = JShellTool.class.getResourceAsStream(spec);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+ return reader.lines().collect(Collectors.joining("\n"));
+ }
}
// retrieve the default startup string
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Tue Jan 24 00:30:23 2017 +0100
@@ -66,7 +66,7 @@
if ((read = input.read()) == (-1)) {
break;
}
- if (read == 3 && currentState == State.BUFFER) {
+ if (read == 3 && getState() == State.BUFFER) {
stop.run();
} else {
write(read);
@@ -141,6 +141,10 @@
}
}
+ private synchronized State getState() {
+ return state;
+ }
+
private synchronized State waitInputNeeded() {
while (state == State.WAIT) {
try {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Tue Jan 24 00:30:23 2017 +0100
@@ -49,6 +49,7 @@
import java.io.Writer;
import java.util.LinkedHashSet;
import java.util.Set;
+import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
import jdk.jshell.Key.ErroneousKey;
import jdk.jshell.Key.MethodKey;
import jdk.jshell.Key.TypeDeclKey;
@@ -58,7 +59,6 @@
import jdk.jshell.TaskFactory.BaseTask;
import jdk.jshell.TaskFactory.CompileTask;
import jdk.jshell.TaskFactory.ParseTask;
-import jdk.jshell.TreeDissector.ExpressionInfo;
import jdk.jshell.Wrap.Range;
import jdk.jshell.Snippet.Status;
import jdk.jshell.spi.ExecutionControl.ClassBytecodes;
@@ -296,7 +296,7 @@
private List<Snippet> processExpression(String userSource, String compileSource) {
String name = null;
- ExpressionInfo ei = typeOfExpression(compileSource);
+ ExpressionInfo ei = ExpressionToTypeInfo.expressionInfo(compileSource, state);
ExpressionTree assignVar;
Wrap guts;
Snippet snip;
@@ -499,16 +499,6 @@
return singletonList(snip);
}
- private ExpressionInfo typeOfExpression(String expression) {
- Wrap guts = Wrap.methodReturnWrap(expression);
- TaskFactory.AnalyzeTask at = trialCompile(guts);
- if (!at.hasErrors() && at.firstCuTree() != null) {
- return TreeDissector.createByFirstClass(at)
- .typeOfReturnStatement(at, state);
- }
- return null;
- }
-
/**
* Should a temp var wrap the expression. TODO make this user configurable.
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionToTypeInfo.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,216 @@
+/*
+ * 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. 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.jshell;
+
+import com.sun.source.tree.ReturnTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ConditionalExpressionTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Types;
+import jdk.jshell.TaskFactory.AnalyzeTask;
+
+/**
+ * Compute information about an expression string, particularly its type name.
+ */
+class ExpressionToTypeInfo {
+
+ private static final String OBJECT_TYPE_NAME = "Object";
+
+ final AnalyzeTask at;
+ final CompilationUnitTree cu;
+ final JShell state;
+ final Symtab syms;
+ final Types types;
+
+ private ExpressionToTypeInfo(AnalyzeTask at, CompilationUnitTree cu, JShell state) {
+ this.at = at;
+ this.cu = cu;
+ this.state = state;
+ this.syms = Symtab.instance(at.context);
+ this.types = Types.instance(at.context);
+ }
+
+ public static class ExpressionInfo {
+ ExpressionTree tree;
+ String typeName;
+ boolean isNonVoid;
+ }
+
+ // return mechanism and other general structure from TreePath.getPath()
+ private static class Result extends Error {
+
+ static final long serialVersionUID = -5942088234594905629L;
+ final TreePath expressionPath;
+
+ Result(TreePath path) {
+ this.expressionPath = path;
+ }
+ }
+
+ private static class PathFinder extends TreePathScanner<TreePath, Boolean> {
+
+ // Optimize out imports etc
+ @Override
+ public TreePath visitCompilationUnit(CompilationUnitTree node, Boolean isTargetContext) {
+ return scan(node.getTypeDecls(), isTargetContext);
+ }
+
+ // Only care about members
+ @Override
+ public TreePath visitClass(ClassTree node, Boolean isTargetContext) {
+ return scan(node.getMembers(), isTargetContext);
+ }
+
+ // Only want the doit method where the code is
+ @Override
+ public TreePath visitMethod(MethodTree node, Boolean isTargetContext) {
+ if (Util.isDoIt(node.getName())) {
+ return scan(node.getBody(), true);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public TreePath visitReturn(ReturnTree node, Boolean isTargetContext) {
+ ExpressionTree tree = node.getExpression();
+ TreePath tp = new TreePath(getCurrentPath(), tree);
+ if (isTargetContext) {
+ throw new Result(tp);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private Type pathToType(TreePath tp) {
+ return (Type) at.trees().getTypeMirror(tp);
+ }
+
+ private Type pathToType(TreePath tp, Tree tree) {
+ if (tree instanceof ConditionalExpressionTree) {
+ // Conditionals always wind up as Object -- this corrects
+ ConditionalExpressionTree cet = (ConditionalExpressionTree) tree;
+ Type tmt = pathToType(new TreePath(tp, cet.getTrueExpression()));
+ Type tmf = pathToType(new TreePath(tp, cet.getFalseExpression()));
+ if (!tmt.isPrimitive() && !tmf.isPrimitive()) {
+ Type lub = types.lub(tmt, tmf);
+ // System.err.printf("cond ? %s : %s -- lub = %s\n",
+ // varTypeName(tmt), varTypeName(tmf), varTypeName(lub));
+ return lub;
+ }
+ }
+ return pathToType(tp);
+ }
+
+ /**
+ * Entry method: get expression info
+ * @param code the expression as a string
+ * @param state a JShell instance
+ * @return type information
+ */
+ public static ExpressionInfo expressionInfo(String code, JShell state) {
+ if (code == null || code.isEmpty()) {
+ return null;
+ }
+ try {
+ OuterWrap codeWrap = state.outerMap.wrapInTrialClass(Wrap.methodReturnWrap(code));
+ AnalyzeTask at = state.taskFactory.new AnalyzeTask(codeWrap);
+ CompilationUnitTree cu = at.firstCuTree();
+ if (at.hasErrors() || cu == null) {
+ return null;
+ }
+ return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ private ExpressionInfo typeOfExpression() {
+ return treeToInfo(findExpressionPath());
+ }
+
+ private TreePath findExpressionPath() {
+ try {
+ new PathFinder().scan(new TreePath(cu), false);
+ } catch (Result result) {
+ return result.expressionPath;
+ }
+ return null;
+ }
+
+ private ExpressionInfo treeToInfo(TreePath tp) {
+ if (tp != null) {
+ Tree tree = tp.getLeaf();
+ if (tree instanceof ExpressionTree) {
+ ExpressionInfo ei = new ExpressionInfo();
+ ei.tree = (ExpressionTree) tree;
+ Type type = pathToType(tp, tree);
+ if (type != null) {
+ switch (type.getKind()) {
+ case VOID:
+ case NONE:
+ case ERROR:
+ case OTHER:
+ break;
+ case NULL:
+ ei.isNonVoid = true;
+ ei.typeName = OBJECT_TYPE_NAME;
+ break;
+ default: {
+ ei.isNonVoid = true;
+ ei.typeName = varTypeName(type);
+ if (ei.typeName == null) {
+ ei.typeName = OBJECT_TYPE_NAME;
+ }
+ break;
+ }
+ }
+ }
+ return ei;
+ }
+ }
+ return null;
+ }
+
+ private String varTypeName(Type type) {
+ try {
+ TypePrinter tp = new VarTypePrinter(at.messages(),
+ state.maps::fullClassNameAndPackageToClass, syms, types);
+ return tp.toString(type);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Tue Jan 24 00:30:23 2017 +0100
@@ -105,7 +105,6 @@
import java.util.stream.Collectors;
import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
@@ -128,6 +127,7 @@
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
+import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
import static jdk.jshell.TreeDissector.printType;
@@ -1430,47 +1430,17 @@
@Override
public String analyzeType(String code, int cursor) {
- code = code.substring(0, cursor);
- CompletionInfo completionInfo = analyzeCompletion(code);
- if (!completionInfo.completeness().isComplete())
- return null;
- if (completionInfo.completeness() == Completeness.COMPLETE_WITH_SEMI) {
- code += ";";
- }
-
- OuterWrap codeWrap;
switch (guessKind(code)) {
case IMPORT: case METHOD: case CLASS: case ENUM:
case INTERFACE: case ANNOTATION_TYPE: case VARIABLE:
return null;
default:
- codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
break;
}
- AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
- SourcePositions sp = at.trees().getSourcePositions();
- CompilationUnitTree topLevel = at.firstCuTree();
- int pos = codeWrap.snippetIndexToWrapIndex(code.length());
- TreePath tp = pathFor(topLevel, sp, pos);
- while (ExpressionTree.class.isAssignableFrom(tp.getParentPath().getLeaf().getKind().asInterface()) &&
- tp.getParentPath().getLeaf().getKind() != Kind.ERRONEOUS &&
- tp.getParentPath().getParentPath() != null)
- tp = tp.getParentPath();
- TypeMirror type = at.trees().getTypeMirror(tp);
-
- if (type == null)
- return null;
-
- switch (type.getKind()) {
- case ERROR: case NONE: case OTHER:
- case PACKAGE: case VOID:
- return null; //not usable
- case NULL:
- type = at.getElements().getTypeElement("java.lang.Object").asType();
- break;
- }
-
- return TreeDissector.printType(at, proc, type);
+ ExpressionInfo ei = ExpressionToTypeInfo.expressionInfo(code, proc);
+ return (ei == null || !ei.isNonVoid)
+ ? null
+ : ei.typeName;
}
@Override
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Tue Jan 24 00:30:23 2017 +0100
@@ -321,7 +321,7 @@
final JavacTaskImpl task;
private DiagList diags = null;
private final SourceHandler<?> sourceHandler;
- private final Context context = new Context();
+ final Context context = new Context();
private Types types;
private JavacMessages messages;
private Trees trees;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java Tue Jan 24 00:30:23 2017 +0100
@@ -28,14 +28,11 @@
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.MethodType;
@@ -47,7 +44,6 @@
import jdk.jshell.Wrap.Range;
import java.util.List;
-import java.util.Locale;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -61,16 +57,6 @@
class TreeDissector {
- private static final String OBJECT_TYPE = "Object";
-
- static class ExpressionInfo {
-
- boolean isNonVoid;
- String typeName;
- ExpressionTree tree;
- String signature;
- }
-
private final TaskFactory.BaseTask bt;
private final ClassTree targetClass;
private final CompilationUnitTree targetCompilationUnit;
@@ -219,41 +205,6 @@
return null;
}
-
- ExpressionInfo typeOfReturnStatement(AnalyzeTask at, JShell state) {
- ExpressionInfo ei = new ExpressionInfo();
- Tree unitTree = firstStatement();
- if (unitTree instanceof ReturnTree) {
- ei.tree = ((ReturnTree) unitTree).getExpression();
- if (ei.tree != null) {
- TreePath viPath = trees().getPath(targetCompilationUnit, ei.tree);
- if (viPath != null) {
- TypeMirror tm = trees().getTypeMirror(viPath);
- if (tm != null) {
- ei.typeName = printType(at, state, tm);
- switch (tm.getKind()) {
- case VOID:
- case NONE:
- case ERROR:
- case OTHER:
- break;
- case NULL:
- ei.isNonVoid = true;
- ei.typeName = OBJECT_TYPE;
- break;
- default: {
- ei.isNonVoid = true;
- break;
-
- }
- }
- }
- }
- }
- }
- return ei;
- }
-
String typeOfMethod(MethodSnippet msn) {
Tree unitTree = method(msn);
if (unitTree instanceof JCMethodDecl) {
@@ -274,8 +225,13 @@
public static String printType(AnalyzeTask at, JShell state, TypeMirror type) {
Type typeImpl = (Type) type;
- TypePrinter tp = new TypePrinter(at.messages(), state.maps::fullClassNameAndPackageToClass, typeImpl);
- return tp.visit(typeImpl, Locale.getDefault());
+ try {
+ TypePrinter tp = new TypePrinter(at.messages(),
+ state.maps::fullClassNameAndPackageToClass);
+ return tp.toString(typeImpl);
+ } catch (Exception ex) {
+ return null;
+ }
}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java Tue Jan 24 00:30:23 2017 +0100
@@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package jdk.jshell;
import static com.sun.tools.javac.code.Flags.COMPOUND;
@@ -41,17 +40,21 @@
* Print types in source form.
*/
class TypePrinter extends Printer {
+
private static final String OBJECT = "Object";
private final JavacMessages messages;
private final BinaryOperator<String> fullClassNameAndPackageToClass;
- private boolean useWildCard = false;
- TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass, Type typeToPrint) {
+ TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass) {
this.messages = messages;
this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
}
+ String toString(Type t) {
+ return visit(t, Locale.getDefault());
+ }
+
@Override
protected String localize(Locale locale, String key, Object... args) {
return messages.getLocalizedString(locale, key, args);
@@ -68,18 +71,6 @@
}
@Override
- public String visitWildcardType(Type.WildcardType wt, Locale locale) {
- if (useWildCard) { // at TypeArgument(ex: List<? extends T>)
- return super.visitWildcardType(wt, locale);
- } else { // at TopLevelType(ex: ? extends List<T>, ? extends Number[][])
- Type extendsBound = wt.getExtendsBound();
- return extendsBound == null
- ? OBJECT
- : visit(extendsBound, locale);
- }
- }
-
- @Override
public String visitType(Type t, Locale locale) {
String s = (t.tsym == null || t.tsym.name == null)
? OBJECT // none
@@ -87,20 +78,9 @@
return s;
}
- @Override
- public String visitClassType(ClassType ct, Locale locale) {
- boolean prevUseWildCard = useWildCard;
- try {
- useWildCard = true;
- return super.visitClassType(ct, locale);
- } finally {
- useWildCard = prevUseWildCard;
- }
- }
-
/**
- * Converts a class name into a (possibly localized) string. Anonymous
- * inner classes get converted into a localized string.
+ * Converts a class name into a (possibly localized) string. Anonymous inner
+ * classes get converted into a localized string.
*
* @param t the type of the class whose name is to be rendered
* @param longform if set, the class' fullname is displayed - if unset the
@@ -112,21 +92,13 @@
protected String className(ClassType t, boolean longform, Locale locale) {
Symbol sym = t.tsym;
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
- /***
- StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
- for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
- s.append('&');
- s.append(visit(is.head, locale));
- }
- return s.toString();
- ***/
return OBJECT;
} else if (sym.name.length() == 0) {
// Anonymous
String s;
ClassType norm = (ClassType) t.tsym.type;
if (norm == null) {
- s = "object";
+ s = OBJECT;
} else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
s = visit(norm.interfaces_field.head, locale);
} else {
@@ -160,7 +132,7 @@
@Override
public String visitPackageSymbol(PackageSymbol s, Locale locale) {
return s.isUnnamed()
- ? "" // Unnamed package
+ ? "" // Unnamed package
: s.fullname.toString();
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Tue Jan 24 00:30:23 2017 +0100
@@ -46,6 +46,7 @@
import static java.util.stream.Collectors.toSet;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_WRAP;
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
@@ -180,6 +181,8 @@
.collect(toList());
// Set the outer wrap for this snippet
si.setOuterWrap(state.outerMap.wrapInClass(except, plus, snippets, wraps));
+ state.debug(DBG_WRAP, "++setWrap() %s\n%s\n",
+ si, si.outerWrap().wrapped());
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarTypePrinter.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,265 @@
+/*
+ * 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. 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.jshell;
+
+import java.util.HashSet;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.util.JavacMessages;
+import java.util.Locale;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+import com.sun.tools.javac.code.BoundKind;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type.CapturedType;
+import com.sun.tools.javac.code.Type.TypeMapping;
+import com.sun.tools.javac.code.Type.TypeVar;
+import com.sun.tools.javac.code.Type.WildcardType;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.code.Types.SimpleVisitor;
+import com.sun.tools.javac.util.List;
+import static com.sun.tools.javac.code.BoundKind.EXTENDS;
+import static com.sun.tools.javac.code.BoundKind.SUPER;
+import static com.sun.tools.javac.code.BoundKind.UNBOUND;
+import static com.sun.tools.javac.code.Type.ArrayType;
+import static com.sun.tools.javac.code.TypeTag.BOT;
+import static com.sun.tools.javac.code.TypeTag.WILDCARD;
+
+/**
+ * Print variable types in source form.
+ * TypeProjection and CaptureScanner are copied from Types in the JEP-286
+ * Sandbox by Maurizio. The checks for Non-Denotable in TypePrinter are
+ * cribbed from denotableChecker of the same source.
+ *
+ * @author Maurizio Cimadamore
+ * @author Robert Field
+ */
+class VarTypePrinter extends TypePrinter {
+ private static final String WILD = "?";
+
+ private final Symtab syms;
+ private final Types types;
+
+ VarTypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass,
+ Symtab syms, Types types) {
+ super(messages, fullClassNameAndPackageToClass);
+ this.syms = syms;
+ this.types = types;
+ }
+
+ @Override
+ String toString(Type t) {
+ return super.toString(upward(t));
+ }
+
+ @Override
+ public String visitTypeVar(TypeVar t, Locale locale) {
+ /* Any type variable mentioned in the inferred type must have been declared as a type parameter
+ (i.e cannot have been produced by inference (18.4))
+ */
+ // and beyond that, there are no global type vars, so if there are any
+ // type variables left, they need to be eliminated
+ return WILD; // Non-denotable
+ }
+
+ @Override
+ public String visitCapturedType(CapturedType t, Locale locale) {
+ /* Any type variable mentioned in the inferred type must have been declared as a type parameter
+ (i.e cannot have been produced by capture conversion (5.1.10))
+ */
+ return WILD; // Non-denotable
+ }
+
+ public Type upward(Type t) {
+ List<Type> captures = captures(t);
+ return upward(t, captures);
+ }
+
+ /************* Following from JEP-286 Types.java ***********/
+
+ public Type upward(Type t, List<Type> vars) {
+ return t.map(new TypeProjection(vars), true);
+ }
+
+ public List<Type> captures(Type t) {
+ CaptureScanner cs = new CaptureScanner();
+ Set<Type> captures = new HashSet<>();
+ cs.visit(t, captures);
+ return List.from(captures);
+ }
+
+ class CaptureScanner extends SimpleVisitor<Void, Set<Type>> {
+
+ @Override
+ public Void visitType(Type t, Set<Type> types) {
+ return null;
+ }
+
+ @Override
+ public Void visitClassType(ClassType t, Set<Type> seen) {
+ if (t.isCompound()) {
+ types.directSupertypes(t).forEach(s -> visit(s, seen));
+ } else {
+ t.allparams().forEach(ta -> visit(ta, seen));
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitArrayType(ArrayType t, Set<Type> seen) {
+ return visit(t.elemtype, seen);
+ }
+
+ @Override
+ public Void visitWildcardType(WildcardType t, Set<Type> seen) {
+ visit(t.type, seen);
+ return null;
+ }
+
+ @Override
+ public Void visitTypeVar(TypeVar t, Set<Type> seen) {
+ if ((t.tsym.flags() & Flags.SYNTHETIC) != 0 && seen.add(t)) {
+ visit(t.getUpperBound(), seen);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitCapturedType(CapturedType t, Set<Type> seen) {
+ if (seen.add(t)) {
+ visit(t.getUpperBound(), seen);
+ visit(t.getLowerBound(), seen);
+ }
+ return null;
+ }
+ }
+
+ class TypeProjection extends TypeMapping<Boolean> {
+
+ List<Type> vars;
+ Set<Type> seen = new HashSet<>();
+
+ public TypeProjection(List<Type> vars) {
+ this.vars = vars;
+ }
+
+ @Override
+ public Type visitClassType(ClassType t, Boolean upward) {
+ if (upward && !t.isCompound() && t.tsym.name.isEmpty()) {
+ //lift anonymous class type to first supertype (class or interface)
+ return types.directSupertypes(t).last();
+ } else if (t.isCompound()) {
+ List<Type> components = types.directSupertypes(t);
+ List<Type> components1 = components.map(c -> c.map(this, upward));
+ if (components == components1) return t;
+ else return types.makeIntersectionType(components1);
+ } else {
+ Type outer = t.getEnclosingType();
+ Type outer1 = visit(outer, upward);
+ List<Type> typarams = t.getTypeArguments();
+ List<Type> typarams1 = typarams.map(ta -> mapTypeArgument(ta, upward));
+ if (typarams1.stream().anyMatch(ta -> ta.hasTag(BOT))) {
+ //not defined
+ return syms.botType;
+ }
+ if (outer1 == outer && typarams1 == typarams) return t;
+ else return new ClassType(outer1, typarams1, t.tsym, t.getMetadata()) {
+ @Override
+ protected boolean needsStripping() {
+ return true;
+ }
+ };
+ }
+ }
+
+ protected Type makeWildcard(Type upper, Type lower) {
+ BoundKind bk;
+ Type bound;
+ if (upper.hasTag(BOT)) {
+ upper = syms.objectType;
+ }
+ boolean isUpperObject = types.isSameType(upper, syms.objectType);
+ if (!lower.hasTag(BOT) && isUpperObject) {
+ bound = lower;
+ bk = SUPER;
+ } else {
+ bound = upper;
+ bk = isUpperObject ? UNBOUND : EXTENDS;
+ }
+ return new WildcardType(bound, bk, syms.boundClass);
+ }
+
+ @Override
+ public Type visitTypeVar(TypeVar t, Boolean upward) {
+ if (vars.contains(t)) {
+ try {
+ if (seen.add(t)) {
+ return (upward ?
+ t.getUpperBound() :
+ (t.getLowerBound() == null) ?
+ syms.botType :
+ t.getLowerBound())
+ .map(this, upward);
+ } else {
+ //cycle
+ return syms.objectType;
+ }
+ } finally {
+ seen.remove(t);
+ }
+ } else {
+ return t;
+ }
+ }
+
+ @Override
+ public Type visitWildcardType(WildcardType wt, Boolean upward) {
+ if (upward) {
+ return wt.isExtendsBound() ?
+ wt.type.map(this, upward) :
+ syms.objectType;
+ } else {
+ return wt.isSuperBound() ?
+ wt.type.map(this, upward) :
+ syms.botType;
+ }
+ }
+
+ private Type mapTypeArgument(Type t, boolean upward) {
+ if (!t.containsAny(vars)) {
+ return t;
+ } else if (!t.hasTag(WILDCARD) && !upward) {
+ //not defined
+ return syms.botType;
+ } else {
+ Type upper = t.map(this, upward);
+ Type lower = t.map(this, !upward);
+ return makeWildcard(upper, lower);
+ }
+ }
+ }
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DefaultLoaderDelegate.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DefaultLoaderDelegate.java Tue Jan 24 00:30:23 2017 +0100
@@ -115,12 +115,6 @@
}
@Override
- public void setClasspath(String path)
- throws EngineTerminationException, InternalException {
- throw new NotImplementedException("setClasspath: Not supported yet.");
- }
-
- @Override
public Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> klass = klasses.get(name);
if (klass == null) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Tue Jan 24 00:30:23 2017 +0100
@@ -131,12 +131,6 @@
loaderDelegate.addToClasspath(cp);
}
- @Override
- public void setClasspath(String path)
- throws EngineTerminationException, InternalException {
- loaderDelegate.setClasspath(path);
- }
-
/**
* {@inheritDoc}
* <p>
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/ExecutionControlForwarder.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/ExecutionControlForwarder.java Tue Jan 24 00:30:23 2017 +0100
@@ -147,12 +147,6 @@
ec.addToClasspath(cp);
return writeSuccess();
}
- case CMD_SET_CLASSPATH: {
- // Set the claspath
- String cp = in.readUTF();
- ec.setClasspath(cp);
- return writeSuccess();
- }
case CMD_STOP: {
// Stop the current execution
try {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LoaderDelegate.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LoaderDelegate.java Tue Jan 24 00:30:23 2017 +0100
@@ -60,16 +60,6 @@
throws EngineTerminationException, InternalException;
/**
- * Sets the execution class path to the specified path.
- *
- * @param path the path to add
- * @throws EngineTerminationException the execution engine has terminated
- * @throws InternalException an internal problem occurred
- */
- void setClasspath(String path)
- throws EngineTerminationException, InternalException;
-
- /**
* Finds the class with the specified binary name.
*
* @param name the binary name of the class
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteCodes.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteCodes.java Tue Jan 24 00:30:23 2017 +0100
@@ -66,10 +66,6 @@
*/
static final String CMD_ADD_CLASSPATH = "CMD_ADD_CLASSPATH";
/**
- * Set the class-path.
- */
- static final String CMD_SET_CLASSPATH = "CMD_SET_CLASSPATH";
- /**
* Stop an invoke.
*/
static final String CMD_STOP = "CMD_STOP";
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/StreamingExecutionControl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/StreamingExecutionControl.java Tue Jan 24 00:30:23 2017 +0100
@@ -137,21 +137,6 @@
}
@Override
- public void setClasspath(String path)
- throws EngineTerminationException, InternalException {
- try {
- // Send the classpath addition command to the remote agent.
- writeCommand(CMD_SET_CLASSPATH);
- out.writeUTF(path);
- out.flush();
- // Retrieve and report results from the remote agent.
- readAndReportClassSimpleResult();
- } catch (IOException ex) {
- throw new EngineTerminationException("Exception writing remote set classpath: " + ex);
- }
- }
-
- @Override
public void stop()
throws EngineTerminationException, InternalException {
try {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControl.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControl.java Tue Jan 24 00:30:23 2017 +0100
@@ -118,16 +118,6 @@
throws EngineTerminationException, InternalException;
/**
- * Sets the execution class path to the specified path.
- *
- * @param path the path to add
- * @throws EngineTerminationException the execution engine has terminated
- * @throws InternalException an internal problem occurred
- */
- void setClasspath(String path)
- throws EngineTerminationException, InternalException;
-
- /**
* Interrupts a running invoke.
*
* @throws EngineTerminationException the execution engine has terminated
--- a/langtools/test/jdk/jshell/CompletionSuggestionTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -673,6 +673,7 @@
keepParameterNames.set(getAnalysis(), new String[0]);
}
+ @Test(enabled = false) //TODO 8171829
public void testBrokenClassFile2() throws IOException {
Path broken = outDir.resolve("broken");
compiler.compile(broken,
--- a/langtools/test/jdk/jshell/KullaTesting.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/jdk/jshell/KullaTesting.java Tue Jan 24 00:30:23 2017 +0100
@@ -99,7 +99,6 @@
private Map<String, Snippet> idToSnippet = new LinkedHashMap<>();
private Set<Snippet> allSnippets = new LinkedHashSet<>();
- private List<String> classpath;
static {
JShell js = JShell.create();
@@ -159,7 +158,6 @@
}
public void addToClasspath(String path) {
- classpath.add(path);
getState().addToClasspath(path);
}
@@ -200,7 +198,6 @@
state = builder.build();
allSnippets = new LinkedHashSet<>();
idToSnippet = new LinkedHashMap<>();
- classpath = new ArrayList<>();
}
@AfterMethod
@@ -210,7 +207,6 @@
analysis = null;
allSnippets = null;
idToSnippet = null;
- classpath = null;
}
public ClassLoader createAndRunFromModule(String moduleName, Path modPath) {
--- a/langtools/test/jdk/jshell/StopExecutionTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/jdk/jshell/StopExecutionTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8171385
* @summary Test JShell#stop
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build KullaTesting TestingInputStream
@@ -30,9 +31,13 @@
*/
import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Consumer;
import jdk.internal.jshell.tool.StopDetectingInputStream;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
@@ -128,4 +133,31 @@
}
}
+ public void testStopDetectingInputBufferWaitStop() throws Exception {
+ Runnable shouldNotHappenRun =
+ () -> { throw new AssertionError("Should not happen."); };
+ Consumer<Exception> shouldNotHappenExc =
+ exc -> { throw new AssertionError("Should not happen.", exc); };
+ StopDetectingInputStream sd = new StopDetectingInputStream(shouldNotHappenRun, shouldNotHappenExc);
+ CountDownLatch reading = new CountDownLatch(1);
+ PipedInputStream is = new PipedInputStream() {
+ @Override
+ public int read() throws IOException {
+ reading.countDown();
+ return super.read();
+ }
+ };
+ PipedOutputStream os = new PipedOutputStream(is);
+
+ sd.setInputStream(is);
+ sd.setState(State.BUFFER);
+ reading.await();
+ sd.setState(State.WAIT);
+ os.write(3);
+ int value = sd.read();
+
+ if (value != 3) {
+ throw new AssertionError();
+ }
+ }
}
--- a/langtools/test/jdk/jshell/TypeNameTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/jdk/jshell/TypeNameTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -23,81 +23,229 @@
/*
* @test
- * @bug 8144903
+ * @bug 8144903 8171981
* @summary Tests for determining the type from the expression
* @build KullaTesting TestingInputStream
* @run testng TypeNameTest
*/
-import jdk.jshell.Snippet;
-import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
-import static jdk.jshell.Snippet.Status.VALID;
import static org.testng.Assert.assertEquals;
@Test
public class TypeNameTest extends KullaTesting {
- public void testReplClassName() {
- assertEval("class C {}");
- VarSnippet sn = (VarSnippet) varKey(assertEval("new C();"));
- assertEquals(sn.typeName(), "C");
+
+ private void assertType(String expr, String type) {
+ assertEquals(varKey(assertEval(expr)).typeName(), type);
+ assertInferredType(expr, type);
+ }
+
+ public void testTypeInference() {
+ assertEval("import java.util.List;");
+ assertEval("import java.util.ArrayList;");
+ assertEval("import java.util.Arrays;");
+
+ assertType("new Object().getClass().getSuperclass() ", "Class<?>");
+ assertType("new ArrayList().getClass().getSuperclass()", "Class<?>");
+ assertType("new ArrayList().getClass()", "Class<? extends ArrayList>");
+ assertType("ArrayList.class", "Class<ArrayList>");
+ assertType("ArrayList.class.getSuperclass()", "Class<? super ArrayList>");
+
+ assertEval("class D<T extends CharSequence> { D<? super T> getS() { return null; } }");
+ assertEval("D<?> d = new D<String>();");
+ assertType("d.getS()", "D<? extends CharSequence>");
+ assertType("null", "Object");
+ assertType("Class.forName( \"java.util.ArrayList\" )", "Class<?>");
+ assertType("new ArrayList<Boolean>() {}", "ArrayList<Boolean>");
+ assertType("new ArrayList<String>().stream()", "java.util.stream.Stream<String>");
+ assertType("Arrays.asList( 1, 2, 3)", "List<Integer>");
+ assertType("new ArrayList().getClass().getClass()", "Class<? extends Class>");
+
+ assertEval("interface A {}");
+ assertEval("interface I {}");
+ assertEval("interface J extends A, I {}");
+ assertEval("interface K extends A, I {}");
+ assertEval("class P<T extends A & I> {}");
+ assertType("(P<?>) null", "P<? extends Object>");
+ }
+
+ public void testConditionals() {
+ assertEval("import java.util.List;");
+ assertEval("import java.util.ArrayList;");
+ assertEval("import java.util.Arrays;");
+
+ assertEval("CharSequence cs = \"hi\";");
+ assertEval("String st = \"low\";");
+ assertEval("boolean b;");
+ assertType("b? cs : st", "CharSequence");
+
+ assertEval("List<String> l1 = Arrays.asList(\"hi\");");
+ assertEval("List<? extends String> l2 = Arrays.asList(\"po\");");
+ assertType("b? l1.get(0) : l2.get(0)", "String");
+
+ assertEval("class X {}");
+ assertEval("class B extends X {}");
+ assertEval("class C extends X {}");
+ assertType("b? new B() : new C()", "X");
+ }
+
+ public void testJEP286NonDenotable() {
+ assertEval("import java.util.List;");
+ assertEval("import java.util.Arrays;");
+ assertEval("import java.util.Iterator;");
+
+ assertEval("List<? extends String> extString() { return Arrays.asList( \"hi\", \"low\" ); }");
+ assertEval("List<? super String> supString() { return Arrays.asList( \"hi\", \"low\" ); }");
+ assertEval("List<?> unbString() { return Arrays.asList( \"hi\", \"low\" ); }");
+ assertEval("List<? extends String>[] extStringArr() {" +
+ " @SuppressWarnings(\"unchecked\") " +
+ "List<? extends String>[] a = new List[1]; a[0] = Arrays.asList(\"hi\"); return a; }");
+ assertEval("List<? super String>[] supStringArr() {" +
+ " @SuppressWarnings(\"unchecked\") " +
+ "List<? super String>[] a = new List[1]; a[0] = Arrays.asList(\"hi\"); return a; }");
+ assertEval("List<?>[] unbStringArr() {" +
+ " @SuppressWarnings(\"unchecked\") " +
+ "List<?>[] a = new List[1]; a[0] = Arrays.asList(\"hi\"); return a; }");
+ assertEval("Iterable<? extends List<? extends String>> extStringIter() {" +
+ "return Arrays.asList( Arrays.asList( \"hi\" ) ); }");
+ assertEval("Iterable<? extends List<? super String>> supStringIter() {" +
+ "return Arrays.asList( Arrays.asList( \"hi\" ) ); }");
+ assertEval("Iterable<? extends List<?>> unbStringIter() {" +
+ "return Arrays.asList( Arrays.asList( \"hi\" ) ); }");
+ assertType("extString()", "List<? extends String>");
+ assertType("extString().get(0)", "String");
+ assertType("supString()", "List<? super String>");
+ assertType("supString().get(0)", "Object");
+ assertType("unbString()", "List<?>");
+ assertType("unbString().get(0)", "Object");
+ assertType("supStringArr()", "List<? super String>[]");
+ assertType("supStringArr()[0]", "List<? super String>");
+ assertType("supStringArr()[0].get(0)", "Object");
+ assertType("unbStringArr()", "List<?>[]");
+ assertType("unbStringArr()[0]", "List<?>");
+ assertType("unbStringArr()[0].get(0)", "Object");
+ assertType("extStringIter()", "Iterable<? extends List<? extends String>>");
+ assertType("extStringIter().iterator()", "Iterator<? extends List<? extends String>>");
+ assertType("extStringIter().iterator().next()", "List<? extends String>");
+ assertType("extStringIter().iterator().next().get(0)", "String");
+ assertType("supStringIter()", "Iterable<? extends List<? super String>>");
+ assertType("supStringIter().iterator()", "Iterator<? extends List<? super String>>");
+ assertType("supStringIter().iterator().next()", "List<? super String>");
+ assertType("supStringIter().iterator().next().get(0)", "Object");
+ assertType("unbStringIter()", "Iterable<? extends List<?>>");
+ assertType("unbStringIter().iterator()", "Iterator<? extends List<?>>");
+ assertType("unbStringIter().iterator().next()", "List<?>");
+ assertType("unbStringIter().iterator().next().get(0)", "Object");
+ }
+
+ public void testJEP286NonDenotable2() {
+ assertEval("import java.util.List;");
+ assertEval("import java.util.Arrays;");
+ assertEval("import java.lang.reflect.Array;");
+
+ assertEval("<Z extends Comparable<Z>> List<? extends Z> extFbound() {" +
+ "return Arrays.asList( (Z)null ); }");
+ assertEval("<Z extends Comparable<Z>> List<? super Z> supFbound() {" +
+ "return Arrays.asList( (Z)null ); }");
+ assertEval("<Z extends Comparable<Z>> List<? extends Z>[] extFboundArr() {" +
+ "@SuppressWarnings(\"unchecked\")" +
+ "List<? extends Z>[] a = new List[1]; a[0] = Arrays.asList( (Z)null ); return a; }");
+ assertEval("<Z extends Comparable<Z>> List<? super Z>[] supFboundArr() {" +
+ "@SuppressWarnings(\"unchecked\")" +
+ "List<? super Z>[] a = new List[1]; a[0] = Arrays.asList( (Z)null ); return a; }");
+ assertEval("<Z extends Comparable<Z>> Iterable<? extends List<? extends Z>> extFboundIter() {" +
+ "return Arrays.asList( Arrays.asList( (Z)null ) ); }");
+ assertEval("<Z extends Comparable<Z>> Iterable<? extends List<? super Z>> supFboundIter() {" +
+ "return Arrays.asList( Arrays.asList( (Z)null ) ); }");
+ assertEval("<Z> List<Z> listOf(Z z) { return Arrays.asList( z ); }");
+ assertEval("<Z> Z[] arrayOf(Z z) {" +
+ "@SuppressWarnings(\"unchecked\")" +
+ "final Z[] a = (Z[]) Array.newInstance(z.getClass(), 1); a[0] = z; return a; }");
+ assertType("extFbound()", "List<? extends Comparable<?>>");
+ assertType("extFbound().get(0)", "Comparable<?>");
+ assertType("supFbound()", "List<?>");
+ assertType("supFbound().get(0)", "Object");
+ assertType("extFboundArr()", "List<? extends Comparable<?>>[]");
+ assertType("extFboundArr()[0]", "List<? extends Comparable<?>>");
+ assertType("extFboundArr()[0].get(0)", "Comparable<?>");
+ assertType("supFboundArr()", "List<?>[]");
+ assertType("supFboundArr()[0]", "List<?>");
+ assertType("supFboundArr()[0].get(0)", "Object");
+ assertType("extFboundIter()", "Iterable<? extends List<? extends Comparable<?>>>");
+ assertType("extFboundIter().iterator()", "java.util.Iterator<? extends List<? extends Comparable<?>>>");
+ assertType("extFboundIter().iterator().next()", "List<? extends Comparable<?>>");
+ assertType("extFboundIter().iterator().next().get(0)", "Comparable<?>");
+ assertType("supFboundIter()", "Iterable<? extends List<?>>");
+ assertType("supFboundIter().iterator()", "java.util.Iterator<? extends List<?>>");
+ assertType("supFboundIter().iterator().next()", "List<?>");
+ assertType("supFboundIter().iterator().next().get(0)", "Object");
+ assertType("listOf(23)", "List<Integer>");
+ assertType("listOf(true)", "List<Boolean>");
+ assertType("listOf(true).get(0)", "Boolean");
+ assertType("arrayOf(99)", "Integer[]");
+ assertType("arrayOf(99)[0]", "Integer");
+
+ assertEval("<Z> Z choose(Z z1, Z z2) { return z1; }");
+ assertType("choose(1, 1L);", "Object");
+ }
+
+ public void testVariableTypeName() {
+ assertType("\"x\"", "String");
+
+ assertType("java.util.regex.Pattern.compile(\"x\")", "java.util.regex.Pattern");
+ assertEval("import java.util.regex.*;");
+ assertType("java.util.regex.Pattern.compile(\"x\")", "Pattern");
+
+ assertType("new java.util.ArrayList()", "java.util.ArrayList");
+ assertEval("import java.util.ArrayList;");
+ assertType("new java.util.ArrayList()", "ArrayList");
+
+ assertType("java.util.Locale.Category.FORMAT", "java.util.Locale.Category");
+ assertEval("import static java.util.Locale.Category;");
+ assertType("java.util.Locale.Category.FORMAT", "Category");
}
public void testReplNestedClassName() {
assertEval("class D { static class E {} }");
- VarSnippet sn = (VarSnippet) varKey(assertEval("new D.E();"));
- assertEquals(sn.typeName(), "D.E");
+ assertType("new D.E();", "D.E");
}
public void testAnonymousClassName() {
assertEval("class C {}");
- VarSnippet sn = (VarSnippet) varKey(assertEval("new C() { int x; };"));
- assertEquals(sn.typeName(), "C");
+ assertType("new C();", "C");
+ assertType("new C() { int x; };", "C");
}
public void testCapturedTypeName() {
- VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass();"));
- assertEquals(sn.typeName(), "Class<? extends String>");
- }
-
- public void testArrayTypeOfCapturedTypeName() {
- VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass().getEnumConstants();"));
- assertEquals(sn.typeName(), "String[]");
+ assertType("\"\".getClass();", "Class<? extends String>");
+ assertType("\"\".getClass().getEnumConstants();", "String[]");
}
public void testJavaLang() {
- VarSnippet sn = (VarSnippet) varKey(assertEval("\"\";"));
- assertEquals(sn.typeName(), "String");
+ assertType("\"\";", "String");
}
public void testNotOverEagerPackageEating() {
- VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass().getDeclaredMethod(\"hashCode\");"));
- assertEquals(sn.typeName(), "java.lang.reflect.Method");
+ assertType("\"\".getClass().getDeclaredMethod(\"hashCode\");", "java.lang.reflect.Method");
}
public void testBounds() {
assertEval("java.util.List<? extends String> list1 = java.util.Arrays.asList(\"\");");
- VarSnippet sn1 = (VarSnippet) varKey(assertEval("list1.iterator().next()"));
- assertEquals(sn1.typeName(), "String");
+ assertType("list1.iterator().next()", "String");
assertEval("java.util.List<? super String> list2 = java.util.Arrays.asList(\"\");");
- VarSnippet sn2 = (VarSnippet) varKey(assertEval("list2.iterator().next()"));
- assertEquals(sn2.typeName(), "Object");
+ assertType("list2.iterator().next()", "Object");
assertEval("java.util.List<?> list3 = java.util.Arrays.asList(\"\");");
- VarSnippet sn3 = (VarSnippet) varKey(assertEval("list3.iterator().next()"));
- assertEquals(sn3.typeName(), "Object");
+ assertType("list3.iterator().next()", "Object");
assertEval("class Test1<X extends CharSequence> { public X get() { return null; } }");
- Snippet x = varKey(assertEval("Test1<?> test1 = new Test1<>();"));
- VarSnippet sn4 = (VarSnippet) varKey(assertEval("test1.get()"));
- assertEquals(sn4.typeName(), "Object");
+ assertEval("Test1<?> test1 = new Test1<>();");
+ assertType("test1.get()", "CharSequence");
assertEval("class Test2<X extends Number & CharSequence> { public X get() { return null; } }");
assertEval("Test2<?> test2 = new Test2<>();");
- VarSnippet sn5 = (VarSnippet) varKey(assertEval("test2.get()"));
- assertEquals(sn5.typeName(), "Object");
- assertEval("class Test3<T> { T[][] get() { return null; } }", added(VALID));
+ assertType("test2.get()", "Object");
+ assertEval("class Test3<T> { T[][] get() { return null; } }");
assertEval("Test3<? extends String> test3 = new Test3<>();");
- VarSnippet sn6 = (VarSnippet) varKey(assertEval("test3.get()"));
- assertEquals(sn6.typeName(), "String[][]");
+ assertType("test3.get()", "String[][]");
}
}
--- a/langtools/test/jdk/jshell/VariablesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/jdk/jshell/VariablesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -337,20 +337,4 @@
assertEquals(unr.get(0), "class undefined");
assertVariables(variable("undefined", "d"));
}
-
- public void variableTypeName() {
- assertEquals(varKey(assertEval("\"x\"")).typeName(), "String");
-
- assertEquals(varKey(assertEval("java.util.regex.Pattern.compile(\"x\")")).typeName(), "java.util.regex.Pattern");
- assertEval("import java.util.regex.*;", added(VALID));
- assertEquals(varKey(assertEval("java.util.regex.Pattern.compile(\"x\")")).typeName(), "Pattern");
-
- assertEquals(varKey(assertEval("new java.util.ArrayList()")).typeName(), "java.util.ArrayList");
- assertEval("import java.util.ArrayList;", added(VALID));
- assertEquals(varKey(assertEval("new java.util.ArrayList()")).typeName(), "ArrayList");
-
- assertEquals(varKey(assertEval("java.util.Locale.Category.FORMAT")).typeName(), "java.util.Locale.Category");
- assertEval("import static java.util.Locale.Category;", added(VALID));
- assertEquals(varKey(assertEval("java.util.Locale.Category.FORMAT")).typeName(), "Category");
- }
}
--- a/langtools/test/tools/javac/T5003235/T5003235a.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/T5003235/T5003235a.java Tue Jan 24 00:30:23 2017 +0100
@@ -3,7 +3,7 @@
* @bug 5003235
* @summary Private inner class accessible from subclasses
* @author Peter von der Ah\u00e9
- * @compile/fail/ref=T5003235a.out --diags:layout=%b:%l:%_%m T5003235a.java
+ * @compile/fail/ref=T5003235a.out -XDrawDiagnostics T5003235a.java
*/
class Super {
--- a/langtools/test/tools/javac/T5003235/T5003235a.out Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/T5003235/T5003235a.out Tue Jan 24 00:30:23 2017 +0100
@@ -1,13 +1,5 @@
-T5003235a.java:21: defaultM() in Super.Inner is defined in an inaccessible class or interface
- i.defaultM();
- ^
-T5003235a.java:22: protectedM() in Super.Inner is defined in an inaccessible class or interface
- i.protectedM();
- ^
-T5003235a.java:23: publicM() in Super.Inner is defined in an inaccessible class or interface
- i.publicM();
- ^
-T5003235a.java:24: privateM() in Super.Inner is defined in an inaccessible class or interface
- i.privateM();
- ^
+T5003235a.java:21:10: compiler.err.not.def.access.class.intf.cant.access: defaultM(), Super.Inner
+T5003235a.java:22:10: compiler.err.not.def.access.class.intf.cant.access: protectedM(), Super.Inner
+T5003235a.java:23:10: compiler.err.not.def.access.class.intf.cant.access: publicM(), Super.Inner
+T5003235a.java:24:10: compiler.err.not.def.access.class.intf.cant.access: privateM(), Super.Inner
4 errors
--- a/langtools/test/tools/javac/T5003235/T5003235b.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/T5003235/T5003235b.java Tue Jan 24 00:30:23 2017 +0100
@@ -3,7 +3,7 @@
* @bug 5003235
* @summary Accessibility of private inner class
* @author Peter von der Ah\u00e9
- * @compile/fail/ref=T5003235b.out --diags:layout=%b:%l:%_%m T5003235b.java
+ * @compile/fail/ref=T5003235b.out -XDrawDiagnostics T5003235b.java
*/
class Outer {
--- a/langtools/test/tools/javac/T5003235/T5003235b.out Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/T5003235/T5003235b.out Tue Jan 24 00:30:23 2017 +0100
@@ -1,13 +1,5 @@
-T5003235b.java:28: k in Outer.Inner is defined in an inaccessible class or interface
- System.out.println("Value of k: " + outer.inner.k);
- ^
-T5003235b.java:29: l in Outer.Inner is defined in an inaccessible class or interface
- System.out.println("Value of l: " + outer.inner.l);
- ^
-T5003235b.java:30: m in Outer.Inner is defined in an inaccessible class or interface
- System.out.println("Value of m: " + outer.inner.m);
- ^
-T5003235b.java:31: n in Outer.Inner is defined in an inaccessible class or interface
- System.out.println("Value of n: " + outer.inner.n);
- ^
+T5003235b.java:28:56: compiler.err.not.def.access.class.intf.cant.access: k, Outer.Inner
+T5003235b.java:29:56: compiler.err.not.def.access.class.intf.cant.access: l, Outer.Inner
+T5003235b.java:30:56: compiler.err.not.def.access.class.intf.cant.access: m, Outer.Inner
+T5003235b.java:31:56: compiler.err.not.def.access.class.intf.cant.access: n, Outer.Inner
4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171325/NPEClearingLocalClassNameIndexesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8171325
+ * @summary NPE in Check.clearLocalClassNameIndexes
+ * @compile/fail/ref=NPEClearingLocalClassNameIndexesTest.out -XDrawDiagnostics NPEClearingLocalClassNameIndexesTest.java
+ */
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class NPEClearingLocalClassNameIndexesTest {
+ <A> void f(List<A> t) {}
+ <B, C> C g(C u, Function<B, C> v) { return null; }
+ <D> D g(Supplier<D> w) { return null; }
+
+ public void test() {
+ f(g((String) null, task -> g(new NoSuch() {})));
+ f(g((String) null, task -> g(new NoSuch<int>() {})));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171325/NPEClearingLocalClassNameIndexesTest.out Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,6 @@
+NPEClearingLocalClassNameIndexesTest.java:18:9: compiler.err.cant.apply.symbol: kindname.method, f, java.util.List<A>, java.lang.String, kindname.class, NPEClearingLocalClassNameIndexesTest, (compiler.misc.incompatible.upper.lower.bounds: C, java.lang.Object,java.util.List<A>, java.lang.String)
+NPEClearingLocalClassNameIndexesTest.java:18:42: compiler.err.cant.resolve.location: kindname.class, NoSuch, , , (compiler.misc.location: kindname.class, NPEClearingLocalClassNameIndexesTest, null)
+NPEClearingLocalClassNameIndexesTest.java:19:9: compiler.err.cant.apply.symbol: kindname.method, f, java.util.List<A>, java.lang.String, kindname.class, NPEClearingLocalClassNameIndexesTest, (compiler.misc.incompatible.upper.lower.bounds: C, java.lang.Object,java.util.List<A>, java.lang.String)
+NPEClearingLocalClassNameIndexesTest.java:19:42: compiler.err.cant.resolve.location: kindname.class, NoSuch, , , (compiler.misc.location: kindname.class, NPEClearingLocalClassNameIndexesTest, null)
+NPEClearingLocalClassNameIndexesTest.java:19:49: compiler.err.type.found.req: int, (compiler.misc.type.req.ref)
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171332/Buggy.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+@Deprecated enum Buggy implements Buggy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171332/Processor.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,21 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8171332
+ * @summary 8171332: NPE in MembersPhase.finishClass
+ * @modules java.compiler
+ * jdk.compiler
+ * @build Processor
+ * @compile/fail/ref=Processor.out -XDrawDiagnostics -processor Processor Buggy.java
+ */
+
+import java.util.Set;
+import javax.annotation.processing.*;
+import javax.lang.model.element.TypeElement;
+
+@SupportedAnnotationTypes("*")
+public class Processor extends AbstractProcessor {
+ @Override
+ public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171332/Processor.out Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,3 @@
+Buggy.java:24:35: compiler.err.intf.expected.here
+Buggy.java:24:13: compiler.err.cyclic.inheritance: Buggy
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171528/DuplicatedAnnotatedPackagesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,6 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8171528
+ * @summary Crash in Annotate with duplicate package-info declarations
+ * @compile/fail/ref=DuplicatedAnnotatedPackagesTest.out -XDrawDiagnostics pkg1/package-info.java pkg2/package-info.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171528/DuplicatedAnnotatedPackagesTest.out Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,4 @@
+package-info.java:2:9: compiler.warn.pkg-info.already.seen: test
+package-info.java:1:1: compiler.err.already.annotated: kindname.package, test
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171528/pkg1/package-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,2 @@
+@Deprecated
+package test;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8171528/pkg2/package-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,2 @@
+@Deprecated
+package test;
--- a/langtools/test/tools/javac/diags/Example.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/diags/Example.java Tue Jan 24 00:30:23 2017 +0100
@@ -61,9 +61,10 @@
declaredKeys = new TreeSet<String>();
srcFiles = new ArrayList<File>();
procFiles = new ArrayList<File>();
- supportFiles = new ArrayList<File>();
srcPathFiles = new ArrayList<File>();
moduleSourcePathFiles = new ArrayList<File>();
+ modulePathFiles = new ArrayList<File>();
+ classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>();
findFiles(file, srcFiles);
@@ -89,10 +90,13 @@
} else if (files == srcFiles && c.getName().equals("additional")) {
additionalFilesDir = c;
findFiles(c, additionalFiles);
- } else if (files == srcFiles && c.getName().equals("support"))
- findFiles(c, supportFiles);
- else
+ } else if (files == srcFiles && c.getName().equals("modulepath")) {
+ findFiles(c, modulePathFiles);
+ } else if (files == srcFiles && c.getName().equals("classpath")) {
+ findFiles(c, classPathFiles);
+ } else {
findFiles(c, files);
+ }
}
} else if (f.isFile()) {
if (f.getName().endsWith(".java")) {
@@ -194,23 +198,32 @@
*/
private void run(PrintWriter out, Set<String> keys, boolean raw, boolean verbose)
throws IOException {
- ClassLoader loader = getClass().getClassLoader();
- if (supportFiles.size() > 0) {
- File supportDir = new File(tempDir, "support");
- supportDir.mkdirs();
- clean(supportDir);
- List<String> sOpts = Arrays.asList("-d", supportDir.getPath());
- new Jsr199Compiler(verbose).run(null, null, false, sOpts, procFiles);
- URLClassLoader ucl =
- new URLClassLoader(new URL[] { supportDir.toURI().toURL() }, loader);
- loader = ucl;
+ List<String> opts = new ArrayList<String>();
+ if (!modulePathFiles.isEmpty()) {
+ File modulepathDir = new File(tempDir, "modulepath");
+ modulepathDir.mkdirs();
+ clean(modulepathDir);
+ List<String> sOpts = Arrays.asList("-d", modulepathDir.getPath(),
+ "--module-source-path", new File(file, "modulepath").getAbsolutePath());
+ new Jsr199Compiler(verbose).run(null, null, false, sOpts, modulePathFiles);
+ opts.add("--module-path");
+ opts.add(modulepathDir.getAbsolutePath());
+ }
+
+ if (!classPathFiles.isEmpty()) {
+ File classpathDir = new File(tempDir, "classpath");
+ classpathDir.mkdirs();
+ clean(classpathDir);
+ List<String> sOpts = Arrays.asList("-d", classpathDir.getPath());
+ new Jsr199Compiler(verbose).run(null, null, false, sOpts, classPathFiles);
+ opts.add("--class-path");
+ opts.add(classpathDir.getAbsolutePath());
}
File classesDir = new File(tempDir, "classes");
classesDir.mkdirs();
clean(classesDir);
- List<String> opts = new ArrayList<String>();
opts.add("-d");
opts.add(classesDir.getPath());
if (options != null)
@@ -327,8 +340,9 @@
File additionalFilesDir;
List<File> srcPathFiles;
List<File> moduleSourcePathFiles;
+ List<File> modulePathFiles;
+ List<File> classPathFiles;
List<File> additionalFiles;
- List<File> supportFiles;
File infoFile;
private List<String> runOpts;
private List<String> options;
--- a/langtools/test/tools/javac/diags/RunExamples.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/diags/RunExamples.java Tue Jan 24 00:30:23 2017 +0100
@@ -239,8 +239,10 @@
srcFiles.remove(e.infoFile);
showFiles(e, srcFiles);
showFiles(e, e.srcPathFiles);
+ showFiles(e, e.moduleSourcePathFiles);
+ showFiles(e, e.modulePathFiles);
+ showFiles(e, e.classPathFiles);
showFiles(e, e.procFiles);
- showFiles(e, e.supportFiles);
}
run(e);
}
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Jan 24 00:30:23 2017 +0100
@@ -20,11 +20,13 @@
compiler.err.limit.stack # Code
compiler.err.limit.string # Gen
compiler.err.limit.string.overflow # JavaCompiler
+compiler.err.module.non.zero.opens # bad class file
compiler.err.name.reserved.for.internal.use # UNUSED
compiler.err.no.annotation.member
compiler.err.no.encl.instance.of.type.in.scope # cannot occur; always followed by assert false;
compiler.err.no.match.entry # UNUSED?
compiler.err.not.annotation.type # cannot occur given preceding checkType
+compiler.err.not.def.access.package.cant.access
compiler.err.proc.bad.config.file # JavacProcessingEnvironment
compiler.err.proc.cant.access # completion failure
compiler.err.proc.cant.access.1 # completion failure, no stack trace
@@ -69,10 +71,11 @@
compiler.misc.kindname.value
compiler.misc.incompatible.eq.lower.bounds # cannot happen?
compiler.misc.module.name.mismatch
+compiler.misc.module.non.zero.opens # bad class file
compiler.misc.no.unique.minimal.instance.exists
compiler.misc.no.unique.maximal.instance.exists # cannot happen?
-compiler.err.module.non.zero.opens # bad class file
-compiler.misc.module.non.zero.opens # bad class file
+compiler.misc.not.def.access.package.cant.access
+compiler.misc.package.not.visible
compiler.misc.resume.abort # prompt for a response
compiler.misc.source.unavailable # DiagnosticSource
compiler.misc.token.bad-symbol
@@ -117,6 +120,7 @@
compiler.misc.bad.const.pool.entry # constant pool entry has wrong type
compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
compiler.warn.invalid.path # this warning is generated only in Windows systems
+compiler.note.multiple.elements # needs user code
# The following module-related messages will have to stay on the not-yet list for various reasons:
compiler.warn.locn.unknown.file.on.module.path # Never issued ATM (short circuited with an if (false))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/NotDefAccessClassIntfCantAccessReason.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.not.def.access.class.intf.cant.access.reason
+//key: compiler.misc.not.def.access.does.not.read
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/apia/api1/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package api1;
+
+public class Api {
+ public static void test() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/apia/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module apia {
+ exports api1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/apib/api2/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package api2;
+
+public class Api {
+ public static api1.Api get() { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/apib/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+module apib {
+ requires apia;
+ exports api2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ void test() {
+ api2.Api.get().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReason/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module impl {
+ requires apib;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/NotDefAccessClassIntfCantAccessReason.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.invalid.mref
+// key: compiler.misc.not.def.access.class.intf.cant.access.reason
+// key: compiler.misc.not.def.access.does.not.read
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/apia/api1/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package api1;
+
+public class Api {
+ public static void test() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/apia/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module apia {
+ exports api1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/apib/api2/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package api2;
+
+public class Api {
+ public static api1.Api get() { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/apib/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+module apib {
+ requires apia;
+ exports api2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ void test(api2.Api a2) {
+ Runnable r = a2.get() :: test;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessReasonFragment/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module impl {
+ requires apib;
+}
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassPackageCantAccess/NotDefAccessClassPackageCantAccess.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-// key: compiler.err.not.def.access.package.cant.access
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassPackageCantAccess/modulesourcepath/m1x/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-module m1x {}
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassPackageCantAccess/modulesourcepath/m1x/p1/C1.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-package p1;
-
-public class C1 {}
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassPackageCantAccess/modulesourcepath/m2x/module-info.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-module m2x {}
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassPackageCantAccess/modulesourcepath/m2x/p2/C2.java Thu Jan 19 10:55:07 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-package p2;
-
-public class C2 {
- p1.C1 c1;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotRead/NotDefAccessDoesNotRead.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.does.not.read
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotRead/modulesourcepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotRead/modulesourcepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module api {
+ exports api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotRead/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotRead/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+module impl {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadFromUnnamed/NotDefAccessDoesNotReadFromUnnamed.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.does.not.read.from.unnamed
+
+public class NotDefAccessDoesNotReadFromUnnamed {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadFromUnnamed/modulepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadFromUnnamed/modulepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module api {
+ exports api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/NotDefAccessDoesNotReadUnnamed.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.not.def.access.class.intf.cant.access.reason
+//key: compiler.misc.not.def.access.does.not.read.unnamed
+//options: --add-reads=auxiliary=ALL-UNNAMED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/classpath/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+ public void test() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/modulesourcepath/auxiliary/auxiliary/Auxiliary.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package auxiliary;
+
+public class Auxiliary {
+ public static api.Api get() { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/modulesourcepath/auxiliary/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module auxiliary {
+ exports auxiliary;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ {
+ auxiliary.Auxiliary.get().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessDoesNotReadUnnamed/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module impl {
+ requires auxiliary;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExported/NotDefAccessNotExported.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.not.exported
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExported/modulesourcepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExported/modulesourcepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+module api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExported/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExported/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module impl {
+ requires api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedFromUnnamed/NotDefAccessNotExportedFromUnnamed.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.not.exported.from.unnamed
+//options: --add-modules api
+
+public class NotDefAccessNotExportedFromUnnamed {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedFromUnnamed/modulepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedFromUnnamed/modulepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+module api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/NotDefAccessNotExportedToModule.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.not.exported.to.module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/modulesourcepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/modulesourcepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module api {
+ exports api to other;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/modulesourcepath/impl/impl/Impl.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package impl;
+
+public class Impl {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/modulesourcepath/impl/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module impl {
+ requires api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModule/modulesourcepath/other/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module other {
+ requires api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModuleFromUnnamed/NotDefAccessNotExportedToModuleFromUnnamed.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+//key: compiler.err.package.not.visible
+//key: compiler.misc.not.def.access.not.exported.to.module.from.unnamed
+//options: --add-modules api
+
+public class NotDefAccessNotExportedToModuleFromUnnamed {
+ api.Api api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModuleFromUnnamed/modulepath/api/api/Api.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package api;
+
+public class Api {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModuleFromUnnamed/modulepath/api/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module api {
+ exports api to other;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessNotExportedToModuleFromUnnamed/modulepath/other/module-info.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module other {
+ requires api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doclint/DocLintFormatTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012, 2017, 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 8172474
+ * @summary javac should enable doclint checking for HTML 5
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask
+ * @run main DocLintFormatTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.ToolBox;
+
+public class DocLintFormatTest {
+ public static void main(String... args) throws Exception {
+ new DocLintFormatTest().run();
+ }
+
+ private ToolBox tb = new ToolBox();
+ private Path src = Paths.get("src");
+ private Path classes = Paths.get("classes");
+
+ void run() throws Exception {
+ Files.createDirectories(classes);
+
+ tb.writeJavaFiles(src,
+ // 1 2
+ //2345678901234567890
+ "/** This is an <tt>HTML 4</tt> comment. */ public class Test4 { }",
+ "/** This is an <mark>HTML 5</mark> comment. */ public class Test5 { }"
+ );
+
+ test(src.resolve("Test4.java"), "html4");
+ test(src.resolve("Test4.java"), "html5",
+ "Test4.java:1:16: compiler.err.proc.messager: tag not supported in the generated HTML version: tt");
+ test(src.resolve("Test5.java"), "html4",
+ "Test5.java:1:16: compiler.err.proc.messager: tag not supported in the generated HTML version: mark");
+ test(src.resolve("Test5.java"), "html5");
+
+ if (errors > 0) {
+ throw new Exception(errors + " errors occurred");
+ }
+ }
+
+ void test(Path file, String format, String... expect) {
+ System.err.println("Test: " + format + " " + file);
+ List<String> output = new JavacTask(tb)
+ .outdir(classes)
+ .options("-XDrawDiagnostics", "-Xdoclint", "--doclint-format", format)
+ .files(file)
+ .run(expect.length == 0 ? Task.Expect.SUCCESS : Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ if (expect.length == 0) {
+ if (!(output.size() == 1 && output.get(0).isEmpty())) {
+ error("All output unexpected.");
+ }
+ } else {
+ for (String e : expect) {
+ if (!output.contains(e)) {
+ error("expected output not found: " + e);
+ }
+ }
+ }
+ }
+
+ void error(String message) {
+ System.err.println("Error: " + message);
+ errors++;
+ }
+
+ private int errors = 0;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReferenceVarargsTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, 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 8171993
+ * @summary AssertionError when compiling method reference with generic code and varargs.
+ * @compile MethodReferenceVarargsTest.java
+ */
+
+public class MethodReferenceVarargsTest<T> {
+ public T invoke(Object... args) {
+ return null;
+ }
+ public static <T extends String> void test() { // works with <T> alone.
+ MethodReferenceVarargsTest<T> bug = new MethodReferenceVarargsTest<>();
+ java.util.function.Function<String, T> b = bug::invoke;
+ java.util.function.Function<String, T> f = (args) -> bug.invoke(args);
+ }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/modules/AddLimitMods.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java Tue Jan 24 00:30:23 2017 +0100
@@ -217,8 +217,8 @@
private static final List<Entry<String[], String>> variants = Arrays.asList(
new SimpleEntry<String[], String>(new String[] {},
- "Test.java:2:18: compiler.err.doesnt.exist: javax.annotation\n"
- + "Test.java:5:19: compiler.err.doesnt.exist: javax.xml.bind\n"
+ "Test.java:2:7: compiler.err.package.not.visible: javax.annotation, (compiler.misc.not.def.access.does.not.read.from.unnamed: javax.annotation, java.annotations.common)\n"
+ + "Test.java:5:14: compiler.err.package.not.visible: javax.xml.bind, (compiler.misc.not.def.access.does.not.read.from.unnamed: javax.xml.bind, java.xml.bind)\n"
+ "2 errors\n"),
new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.annotations.common,java.xml.bind"},
null),
--- a/langtools/test/tools/javac/modules/AddReadsTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/AddReadsTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -81,7 +81,7 @@
.getOutput(Task.OutputKind.DIRECT);
checkOutputContains(log,
- "Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api");
+ "Test.java:1:41: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)");
//test add dependencies:
new JavacTask(tb)
--- a/langtools/test/tools/javac/modules/AnnotationProcessing.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/AnnotationProcessing.java Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8133884 8162711 8133896 8172158
+ * @bug 8133884 8162711 8133896 8172158 8172262
* @summary Verify that annotation processing works.
* @library /tools/lib
* @modules
@@ -50,6 +50,7 @@
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Function;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor;
@@ -1067,24 +1068,43 @@
"package impl1; public class Impl { }",
"package impl.conflict.module; class Impl { }",
"package impl.conflict.clazz; public class pkg { public static class I { } }",
- "package impl.conflict.src; public class Impl { }");
+ "package impl.conflict.src; public class Impl { }",
+ "package nested.pack.pack; public class Impl { }",
+ "package unique.nested; public class Impl { }");
tb.writeJavaFiles(m2,
"module m2x { }",
"package impl2; public class Impl { }",
"package impl.conflict.module; class Impl { }",
- "package impl.conflict; public class clazz { public static class pkg { } }");
+ "package impl.conflict; public class clazz { public static class pkg { } }",
+ "package nested.pack; public class Impl { }");
//from source:
- new JavacTask(tb)
+ String log = new JavacTask(tb)
.options("--module-source-path", moduleSrc.toString(),
"--source-path", src.toString(),
"-processorpath", System.getProperty("test.class.path"),
- "-processor", UnboundLookup.class.getName())
+ "-processor", UnboundLookup.class.getName(),
+ "-XDrawDiagnostics")
.outdir(classes)
.files(findJavaFiles(moduleSrc))
.run()
- .writeAll();
+ .writeAll()
+ .getOutput(OutputKind.DIRECT);
+
+ String moduleImplConflictString =
+ "- compiler.note.multiple.elements: getTypeElement, impl.conflict.module.Impl, m2x, m1x";
+ String srcConflictString =
+ "- compiler.note.multiple.elements: getTypeElement, impl.conflict.src.Impl, m1x, unnamed module";
+
+ if (!log.contains(moduleImplConflictString) ||
+ !log.contains(srcConflictString)) {
+ throw new AssertionError("Expected output not found: " + log);
+ }
+
+ if (log.split(Pattern.quote(moduleImplConflictString)).length > 2) {
+ throw new AssertionError("Too many warnings in: " + log);
+ }
new JavacTask(tb)
.options("--source-path", src.toString())
@@ -1130,11 +1150,17 @@
assertTypeElementExists("impl.conflict.clazz", "m2x");
assertPackageElementExists("impl.conflict.clazz", "m1x");
assertPackageElementExists("impl2", "m2x");
+ assertPackageElementExists("nested.pack.pack", "m1x");
+ assertPackageElementExists("nested.pack", "m2x");
+ assertTypeElementExists("unique.nested.Impl", "m1x");
assertTypeElementNotFound("impl.conflict.module.Impl");
+ assertTypeElementNotFound("impl.conflict.module.Impl"); //check that the warning/note is produced only once
assertPackageElementNotFound("impl.conflict.module");
assertTypeElementNotFound("impl.conflict.src.Impl");
assertPackageElementNotFound("impl.conflict.src");
assertTypeElementNotFound("impl.conflict.clazz.pkg");
+ assertPackageElementNotFound("unique"); //do not return packages without members in module mode
+ assertTypeElementNotFound("nested"); //cannot distinguish between m1x and m2x
return false;
}
--- a/langtools/test/tools/javac/modules/AutomaticModules.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/AutomaticModules.java Tue Jan 24 00:30:23 2017 +0100
@@ -283,7 +283,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("Impl.java:1:62: compiler.err.not.def.access.package.cant.access: m2x.M2, m2x",
+ List<String> expected = Arrays.asList("Impl.java:1:59: compiler.err.package.not.visible: m2x, (compiler.misc.not.def.access.does.not.read: m1x, m2x, m2x)",
"1 error");
if (!expected.equals(log)) {
@@ -300,8 +300,8 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- expected = Arrays.asList("Impl.java:1:51: compiler.err.doesnt.exist: apiB",
- "Impl.java:1:62: compiler.err.not.def.access.package.cant.access: m2x.M2, m2x",
+ expected = Arrays.asList("Impl.java:1:47: compiler.err.package.not.visible: apiB, (compiler.misc.not.def.access.does.not.read: m1x, apiB, automaticB)",
+ "Impl.java:1:59: compiler.err.package.not.visible: m2x, (compiler.misc.not.def.access.does.not.read: m1x, m2x, m2x)",
"2 errors");
if (!expected.equals(log)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,596 @@
+/*
+ * 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 8169197 8172668
+ * @summary Check convenient errors are produced for inaccessible classes.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
+ * @run main ConvenientAccessErrorsTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+import toolbox.JarTask;
+import toolbox.JavacTask;
+import toolbox.Task;
+
+public class ConvenientAccessErrorsTest extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new ConvenientAccessErrorsTest().runTests();
+ }
+
+ @Test
+ public void testNoDep(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; }",
+ "package api; public class Api { public void call() { } }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { }",
+ "package test; public class Test { api.Api api; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:35: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testNotExported(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; }",
+ "package api; public class Api { }",
+ "package impl; public class Impl { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test; public class Test { impl.Impl api; }");
+ Path src_m3 = src.resolve("m3x");
+ tb.writeJavaFiles(src_m3,
+ "module m3x { requires m1x; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:35: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported: impl, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; exports impl to m3x;}");
+
+ log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "Test.java:1:35: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported.to.module: impl, m1x, m2x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testInaccessibleInExported(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; }",
+ "package api; class Api { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test; public class Test { api.Api api; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:38: compiler.err.not.def.public.cant.access: api.Api, api",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+// @Test
+ public void testInaccessibleUnnamedModule(Path base) throws Exception {
+ Path jar = prepareTestJar(base, "package api; class Api { public static class Foo {} }");
+
+ Path moduleSrc = base.resolve("module-src");
+ Path m1x = moduleSrc.resolve("m1x");
+
+ Path classes = base.resolve("classes");
+
+ Files.createDirectories(classes);
+
+ tb.writeJavaFiles(m1x,
+ "module m1x { }",
+ "package test; public class Test { api.Api api; api.Api.Foo api; }");
+
+ List<String> log = new JavacTask(tb)
+ .options("-classpath", jar.toString(),
+ "-XDrawDiagnostics")
+ .outdir(classes)
+ .files(findJavaFiles(moduleSrc))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:38: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)",
+ "Test.java:1:51: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)",
+ "2 errors");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testIndirectReferenceToUnnamedModule(Path base) throws Exception {
+ Path jar = prepareTestJar(base, "package api; public class Api { public void test() {} }");
+
+ Path moduleSrc = base.resolve("module-src");
+ Path m1x = moduleSrc.resolve("m1x");
+ Path auxiliary = moduleSrc.resolve("auxiliary");
+
+ Path classes = base.resolve("classes");
+
+ Files.createDirectories(classes);
+
+ tb.writeJavaFiles(m1x,
+ "module m1x { requires auxiliary; }",
+ "package test; public class Test { { auxiliary.Auxiliary.get().test(); } }");
+
+ tb.writeJavaFiles(auxiliary,
+ "module auxiliary { exports auxiliary; }",
+ "package auxiliary; public class Auxiliary { public static api.Api get() { return null; } }");
+
+ List<String> log = new JavacTask(tb)
+ .options("-classpath", jar.toString(),
+ "-XDrawDiagnostics",
+ "--add-reads", "auxiliary=ALL-UNNAMED",
+ "--module-source-path", moduleSrc.toString())
+ .outdir(classes)
+ .files(findJavaFiles(moduleSrc))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:62: compiler.err.not.def.access.class.intf.cant.access.reason: test(), api.Api, api, (compiler.misc.not.def.access.does.not.read.unnamed: api, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ private Path prepareTestJar(Path base, String code) throws Exception {
+ Path legacySrc = base.resolve("legacy-src");
+ tb.writeJavaFiles(legacySrc, code);
+ Path legacyClasses = base.resolve("legacy-classes");
+ Files.createDirectories(legacyClasses);
+
+ String log = new JavacTask(tb)
+ .options()
+ .outdir(legacyClasses)
+ .files(findJavaFiles(legacySrc))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.isEmpty()) {
+ throw new Exception("unexpected output: " + log);
+ }
+
+ Path lib = base.resolve("lib");
+
+ Files.createDirectories(lib);
+
+ Path jar = lib.resolve("test-api-1.0.jar");
+
+ new JarTask(tb, jar)
+ .baseDir(legacyClasses)
+ .files("api/Api.class")
+ .run();
+
+ return jar;
+ }
+
+ @Test
+ public void testUnnamedModuleAccess(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api to m2x; }",
+ "package api; class Api { }",
+ "package impl; class Impl { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }");
+ Path modulepath = base.resolve("modulepath");
+ tb.createDirectories(modulepath);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src.toString())
+ .outdir(modulepath)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ Path unnamedSrc = base.resolve("unnamedSrc");
+ tb.writeJavaFiles(unnamedSrc,
+ "public class Test { api.Api api; impl.Impl impl; }");
+ Path unnamedClasses = base.resolve("unnamed-classes");
+ Files.createDirectories(unnamedClasses);
+
+ List<String> log = new JavacTask(tb)
+ .options("--module-path", modulepath.toString(),
+ "-XDrawDiagnostics")
+ .outdir(unnamedClasses)
+ .files(findJavaFiles(unnamedSrc))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:21: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, m1x)",
+ "Test.java:1:34: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.does.not.read.from.unnamed: impl, m1x)",
+ "2 errors"
+ );
+
+ if (!expected.equals(log)) {
+ throw new Exception("unexpected output: " + log);
+ }
+
+ log = new JavacTask(tb)
+ .options("--module-path", modulepath.toString(),
+ "--add-modules", "m1x",
+ "-XDrawDiagnostics")
+ .outdir(unnamedClasses)
+ .files(findJavaFiles(unnamedSrc))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList(
+ "Test.java:1:21: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported.to.module.from.unnamed: api, m1x)",
+ "Test.java:1:34: compiler.err.package.not.visible: impl, (compiler.misc.not.def.access.not.exported.from.unnamed: impl, m1x)",
+ "2 errors"
+ );
+
+ if (!expected.equals(log)) {
+ throw new Exception("unexpected output: " + log);
+ }
+ }
+
+ @Test
+ public void testInImport(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }",
+ "package api; public class Api { public String test() { return null; } }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test; import api.Api; public class Test { Api api; { api.test().length(); } }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testInImportOnDemand(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }",
+ "package api; public class Api { public String test() { return null; } }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test; import api.*; public class Test { Api api; { api.test().length(); } }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)",
+ "Test.java:1:49: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.not.exported: api, m1x)",
+ "2 errors");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testUnusedImportOnDemand1(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "package test; import javax.annotation.*; public class Test { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--add-modules", "java.compiler")
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList("");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testUnusedImportOnDemand2(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }",
+ "package api; public class Api { }");
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test; import api.*; public class Test { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testClassPackageConflict(Path base) throws Exception {
+ Path libSrc = base.resolve("libSrc");
+ tb.writeJavaFiles(libSrc,
+ "package test.desktop; public class Any { }");
+ Path libClasses = base.resolve("libClasses");
+ tb.createDirectories(libClasses);
+
+ new JavacTask(tb)
+ .outdir(libClasses)
+ .files(findJavaFiles(libSrc))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "package test; public class desktop { public static class Action { } }",
+ "package use; import test.desktop.*; public class Use { test.desktop.Action a; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .classpath(libClasses)
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+ }
+
+ @Test
+ public void testClassPackageConflictInUnnamed(Path base) throws Exception {
+ Path libSrc = base.resolve("libSrc");
+ tb.writeJavaFiles(libSrc,
+ "package desktop; public class Any { }");
+ Path libClasses = base.resolve("libClasses");
+ tb.createDirectories(libClasses);
+
+ new JavacTask(tb)
+ .outdir(libClasses)
+ .files(findJavaFiles(libSrc))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "public class desktop { public static class Action { } }",
+ "import desktop.*; public class Use { desktop.Action a; }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .classpath(libClasses)
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+ }
+
+ @Test
+ public void testUnresolvableInImport(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { }",
+ "package api; import can.not.resolve; public class Api { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Api.java:1:28: compiler.err.doesnt.exist: can.not",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+ @Test
+ public void testMissingKnownClass(Path base) throws Exception {
+ Path src = base.resolve("src");
+ Path src_m1 = src.resolve("m1x");
+ tb.writeJavaFiles(src_m1,
+ "module m1x { exports api; }",
+ "package api; public class Base { }",
+ "package api; public class Sub extends Base { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+ Path m1xClasses = classes.resolve("m1x");
+ tb.createDirectories(m1xClasses);
+
+ new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .outdir(m1xClasses)
+ .files(findJavaFiles(src_m1))
+ .run(Task.Expect.SUCCESS)
+ .writeAll();
+
+ Files.delete(m1xClasses.resolve("api").resolve("Base.class"));
+
+ Path src_m2 = src.resolve("m2x");
+ tb.writeJavaFiles(src_m2,
+ "module m2x { requires m1x; }",
+ "package test;\n" +
+ "import api.Sub;\n" +
+ "import api.Base;\n" +
+ "public class Test {\n" +
+ " Sub a2;\n" +
+ " Base a;\n" +
+ "}\n");
+ Path m2xClasses = classes.resolve("m2x");
+ tb.createDirectories(m2xClasses);
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-path", classes.toString(),
+ "-XDdev")
+ .outdir(m2xClasses)
+ .files(findJavaFiles(src_m2))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList(
+ "Test.java:3:11: compiler.err.cant.resolve.location: kindname.class, Base, , , (compiler.misc.location: kindname.package, api, null)",
+ "Test.java:6:5: compiler.err.cant.resolve.location: kindname.class, Base, , , (compiler.misc.location: kindname.class, test.Test, null)",
+ "2 errors");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found; actual: " + log);
+ }
+
+}
--- a/langtools/test/tools/javac/modules/EdgeCases.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/EdgeCases.java Tue Jan 24 00:30:23 2017 +0100
@@ -178,7 +178,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("Test.java:1:52: compiler.err.not.def.access.class.intf.cant.access: call(), api1.Api1") ||
+ if (!log.contains("Test.java:1:52: compiler.err.not.def.access.class.intf.cant.access.reason: call(), api1.Api1, api1, (compiler.misc.not.def.access.does.not.read: m3x, api1, m1x)") ||
!log.contains("Test.java:1:76: compiler.err.not.def.access.class.intf.cant.access: toString(), java.lang.Object"))
throw new Exception("expected output not found");
}
--- a/langtools/test/tools/javac/modules/GraphsTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/GraphsTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -134,9 +134,9 @@
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList(
- "Negative.java:1:43: compiler.err.doesnt.exist: closedO",
- "Negative.java:1:56: compiler.err.doesnt.exist: closedN",
- "Negative.java:1:69: compiler.err.doesnt.exist: closedL");
+ "Negative.java:1:36: compiler.err.package.not.visible: closedO, (compiler.misc.not.def.access.not.exported: closedO, O)",
+ "Negative.java:1:49: compiler.err.package.not.visible: closedN, (compiler.misc.not.def.access.not.exported: closedN, N)",
+ "Negative.java:1:62: compiler.err.package.not.visible: closedL, (compiler.misc.not.def.access.not.exported: closedL, L)");
if (!log.containsAll(expected)) {
throw new Exception("Expected output not found");
}
@@ -153,9 +153,9 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
expected = Arrays.asList(
- "Negative.java:1:43: compiler.err.not.def.access.package.cant.access: closedO.O, closedO",
- "Negative.java:1:56: compiler.err.not.def.access.package.cant.access: closedN.N, closedN",
- "Negative.java:1:69: compiler.err.not.def.access.package.cant.access: closedL.L, closedL");
+ "Negative.java:1:36: compiler.err.package.not.visible: closedO, (compiler.misc.not.def.access.not.exported: closedO, O)",
+ "Negative.java:1:49: compiler.err.package.not.visible: closedN, (compiler.misc.not.def.access.not.exported: closedN, N)",
+ "Negative.java:1:62: compiler.err.package.not.visible: closedL, (compiler.misc.not.def.access.not.exported: closedL, L)");
if (!out.containsAll(expected)) {
throw new Exception("Expected output not found");
}
@@ -201,7 +201,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- String expected = "A.java:1:35: compiler.err.not.def.access.package.cant.access: pack.Clazz, pack";
+ String expected = "A.java:1:31: compiler.err.package.not.visible: pack, (compiler.misc.not.def.access.not.exported.to.module: pack, N, L)";
if (!log.contains(expected)) {
throw new Exception("Expected output not found");
}
--- a/langtools/test/tools/javac/modules/LimitModulesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/LimitModulesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -180,7 +180,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C.java:1:41: compiler.err.doesnt.exist: com.sun.tools.javac"))
+ if (!log.contains("C.java:1:35: compiler.err.package.not.visible: com.sun.tools.javac, (compiler.misc.not.def.access.does.not.read.from.unnamed: com.sun.tools.javac, jdk.compiler)"))
throw new Exception("expected output not found");
}
}
--- a/langtools/test/tools/javac/modules/OpenModulesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/OpenModulesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -117,7 +117,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected2 = Arrays.asList("Test.java:1:53: compiler.err.doesnt.exist: api2",
+ List<String> expected2 = Arrays.asList("Test.java:1:49: compiler.err.package.not.visible: api2, (compiler.misc.not.def.access.not.exported: api2, m1x)",
"1 error");
if (!Objects.equals(log2, expected2))
throw new Exception("expected output not found: " + log2);
@@ -180,7 +180,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected2 = Arrays.asList("Test.java:1:53: compiler.err.doesnt.exist: api2",
+ List<String> expected2 = Arrays.asList("Test.java:1:49: compiler.err.package.not.visible: api2, (compiler.misc.not.def.access.not.exported: api2, m1x)",
"1 error");
if (!Objects.equals(log2, expected2))
throw new Exception("expected output not found: " + log2);
--- a/langtools/test/tools/javac/modules/PackageMultipleModules.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/PackageMultipleModules.java Tue Jan 24 00:30:23 2017 +0100
@@ -70,8 +70,8 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("A.java:1:26: compiler.err.not.def.access.package.cant.access: test.B, test",
- "B.java:1:26: compiler.err.not.def.access.package.cant.access: test.A, test",
+ List<String> expected = Arrays.asList("A.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m1x, test, m2x)",
+ "B.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m2x, test, m1x)",
"2 errors");
if (!log.equals(expected))
throw new Exception("expected output not found");
--- a/langtools/test/tools/javac/modules/RequiresStaticTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/RequiresStaticTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -88,7 +88,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("Test.java:1:27: compiler.err.doesnt.exist: com.sun.source.tree"))
+ if (!log.contains("Test.java:1:22: compiler.err.package.not.visible: com.sun.source.tree, (compiler.misc.not.def.access.does.not.read: m, com.sun.source.tree, jdk.compiler)"))
throw new Exception("expected output not found");
}
@@ -124,18 +124,10 @@
.getOutput(Task.OutputKind.DIRECT);
String[] expect = {
- "C1.java:5:10: compiler.err.not.def.access.package.cant.access: p5.C5, p5",
- "C1.java:5:24: compiler.err.not.def.access.package.cant.access: p6.C6, p6",
- "C1.java:5:38: compiler.err.not.def.access.package.cant.access: p7.C7, p7",
- "C1.java:5:52: compiler.err.not.def.access.package.cant.access: p8.C8, p8",
- "C1.java:8:1: compiler.err.cant.resolve.location: kindname.class, C5, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)",
- "C1.java:8:8: compiler.err.cant.resolve.location: kindname.class, C6, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)",
- "C1.java:8:15: compiler.err.cant.resolve.location: kindname.class, C7, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)",
- "C1.java:8:22: compiler.err.cant.resolve.location: kindname.class, C8, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)"
+ "C1.java:5:8: compiler.err.package.not.visible: p5, (compiler.misc.not.def.access.does.not.read: m1x, p5, m5x)",
+ "C1.java:5:22: compiler.err.package.not.visible: p6, (compiler.misc.not.def.access.does.not.read: m1x, p6, m6x)",
+ "C1.java:5:36: compiler.err.package.not.visible: p7, (compiler.misc.not.def.access.does.not.read: m1x, p7, m7x)",
+ "C1.java:5:50: compiler.err.package.not.visible: p8, (compiler.misc.not.def.access.does.not.read: m1x, p8, m8x)"
};
for (String e: expect) {
--- a/langtools/test/tools/javac/modules/RequiresTransitiveTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/RequiresTransitiveTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -85,7 +85,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("Test.java:1:27: compiler.err.doesnt.exist: com.sun.source.tree"))
+ if (!log.contains("Test.java:1:22: compiler.err.package.not.visible: com.sun.source.tree, (compiler.misc.not.def.access.does.not.read: m, com.sun.source.tree, jdk.compiler)"))
throw new Exception("expected output not found");
}
@@ -121,15 +121,9 @@
.getOutput(Task.OutputKind.DIRECT);
String[] expect = {
- "C1.java:5:10: compiler.err.not.def.access.package.cant.access: p5.C5, p5",
- "C1.java:5:24: compiler.err.not.def.access.package.cant.access: p6.C6, p6",
- "C1.java:5:38: compiler.err.not.def.access.package.cant.access: p7.C7, p7",
- "C1.java:8:1: compiler.err.cant.resolve.location: kindname.class, C5, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)",
- "C1.java:8:8: compiler.err.cant.resolve.location: kindname.class, C6, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)",
- "C1.java:8:15: compiler.err.cant.resolve.location: kindname.class, C7, , , "
- + "(compiler.misc.location: kindname.class, p1.C1, null)"
+ "C1.java:5:8: compiler.err.package.not.visible: p5, (compiler.misc.not.def.access.does.not.read: m1x, p5, m5x)",
+ "C1.java:5:22: compiler.err.package.not.visible: p6, (compiler.misc.not.def.access.does.not.read: m1x, p6, m6x)",
+ "C1.java:5:36: compiler.err.package.not.visible: p7, (compiler.misc.not.def.access.does.not.read: m1x, p7, m7x)"
};
for (String e: expect) {
--- a/langtools/test/tools/javac/modules/ResolveTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/ResolveTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -99,7 +99,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C2.java:1:33: compiler.err.not.def.access.package.cant.access: p1.C1, p1"))
+ if (!log.contains("C2.java:1:31: compiler.err.package.not.visible: p1, (compiler.misc.not.def.access.does.not.read: m2x, p1, m1x)"))
throw new Exception("expected output not found");
}
@@ -123,7 +123,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C2.java:1:33: compiler.err.not.def.access.package.cant.access: p1.C1, p1"))
+ if (!log.contains("C2.java:1:31: compiler.err.package.not.visible: p1, (compiler.misc.not.def.access.not.exported: p1, m1x)"))
throw new Exception("expected output not found");
}
@@ -149,7 +149,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C2.java:1:33: compiler.err.not.def.access.package.cant.access: p1.C1, p1"))
+ if (!log.contains("C2.java:1:31: compiler.err.package.not.visible: p1, (compiler.misc.not.def.access.not.exported.to.module: p1, m1x, m2x)"))
throw new Exception("expected output not found");
}
@@ -173,7 +173,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("C2.java:1:33: compiler.err.not.def.access.package.cant.access: p1.C1, p1"))
+ if (!log.contains("C2.java:1:31: compiler.err.package.not.visible: p1, (compiler.misc.not.def.access.does.not.read: m2x, p1, m1x)"))
throw new Exception("expected output not found");
}
--- a/langtools/test/tools/javac/modules/UsesTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/UsesTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -262,7 +262,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.access.package.cant.access: p.C, p",
+ List<String> expected = Arrays.asList("module-info.java:1:33: compiler.err.package.not.visible: p, (compiler.misc.not.def.access.not.exported: p, m1x)",
"1 error");
if (!output.containsAll(expected)) {
throw new Exception("Expected output not found");
@@ -286,7 +286,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.access.package.cant.access: p.C, p",
+ List<String> expected = Arrays.asList("module-info.java:1:33: compiler.err.package.not.visible: p, (compiler.misc.not.def.access.not.exported: p, m1x)",
"1 error");
if (!output.containsAll(expected)) {
throw new Exception("Expected output not found");
--- a/langtools/test/tools/javac/modules/XModuleTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/langtools/test/tools/javac/modules/XModuleTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -288,7 +288,7 @@
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
- List<String> expected = Arrays.asList("A.java:1:36: compiler.err.doesnt.exist: pkg2",
+ List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)",
"1 error");
if (!expected.equals(log))
--- a/make/Bundles.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/Bundles.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -77,9 +77,8 @@
$$(call MakeDir, $$(@D))
ifneq ($$($1_SPECIAL_INCLUDES), )
$$(foreach i, $$($1_SPECIAL_INCLUDES), \
- $$(foreach d, $$d, \
- ($(CD) $$d && $(FIND) $$i \
- >> $(SUPPORT_OUTPUTDIR)/bundles/_$1_files ) ; ))
+ $$(foreach d, $$($1_BASE_DIRS), \
+ ($(CD) $$d && $(FIND) $$i >> $$($1_$$d_LIST_FILE)) ; ))
endif
ifeq ($$($1_SUBDIR)-$$($1_TYPE)-$$($1_UNZIP_DEBUGINFO), .-zip-false)
# If no subdir is specified, zip can be done directly from BASE_DIRS.
--- a/make/CompileJavaModules.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/CompileJavaModules.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -383,6 +383,10 @@
################################################################################
+jdk.jartool_ADD_JAVAC_FLAGS := -XDstringConcat=inline
+
+################################################################################
+
jdk.rmic_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS
jdk.rmic_CLEAN := .properties
--- a/make/InitSupport.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/InitSupport.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -460,27 +460,28 @@
endef
define PrintFailureReports
- $(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*), \
- $(PRINTF) "=== Output from failing command(s) repeated here ===\n" $(NEWLINE) \
- $(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*)), \
+ $(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log), \
+ $(PRINTF) "\n=== Output from failing command(s) repeated here ===\n" $(NEWLINE) \
+ $(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*.log)), \
$(PRINTF) "* For target $(notdir $(basename $(logfile))):\n" $(NEWLINE) \
($(GREP) -v -e "^Note: including file:" < $(logfile) || true) | $(HEAD) -n 12 $(NEWLINE) \
if test `$(WC) -l < $(logfile)` -gt 12; then \
$(ECHO) " ... (rest of output omitted)" ; \
fi $(NEWLINE) \
) \
+ $(PRINTF) "\n* All command lines available in $(MAKESUPPORT_OUTPUTDIR)/failure-logs.\n" $(NEWLINE) \
$(PRINTF) "=== End of repeated output ===\n" \
)
endef
define PrintBuildLogFailures
if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \
- $(PRINTF) "=== Make failure sequence repeated here ===\n" ; \
+ $(PRINTF) "\n=== Make failed targets repeated here ===\n" ; \
$(GREP) "recipe for target .* failed" $(BUILD_LOG) ; \
$(PRINTF) "=== End of repeated output ===\n" ; \
- $(PRINTF) "Hint: Try searching the build log for the name of the first failed target.\n" ; \
+ $(PRINTF) "\nHint: Try searching the build log for the name of the first failed target.\n" ; \
else \
- $(PRINTF) "No indication of failed target found.\n" ; \
+ $(PRINTF) "\nNo indication of failed target found.\n" ; \
$(PRINTF) "Hint: Try searching the build log for '] Error'.\n" ; \
fi
endef
--- a/make/Javadoc.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/Javadoc.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -683,22 +683,6 @@
TARGETS += $(jdknet)
################################################################################
-
-# TODO: Need to decide when the plugin API is ready to publish as experimental API.
-# This target is temporarily added for internal use for now.
-$(eval $(call SetupJavadocGeneration, jlinkplugins, \
- MODULES := jdk.jlink, \
- PACKAGES := jdk.tools.jlink.plugin, \
- API_ROOT := jdk, \
- DEST_DIR := jlink, \
- TITLE := JLink Plugin API - EXPERIMENTAL, \
- FIRST_COPYRIGHT_YEAR := 2015, \
- DISABLED_DOCLINT := html missing syntax, \
-))
-
-TARGETS += $(jlinkplugins)
-
-################################################################################
# Copy JDWP html file
JDWP_HTML := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/jdwp-protocol.html
--- a/make/Main.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/Main.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -247,7 +247,7 @@
define DeclareHotspotGensrcRecipe
hotspot-$1-gensrc:
$$(call LogInfo, Building JVM variant '$1' with features '$(JVM_FEATURES_$1)')
- +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f gensrc/GenerateSources.gmk \
+ +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f gensrc/GenerateSources.gmk \
JVM_VARIANT=$1)
endef
@@ -255,14 +255,14 @@
define DeclareHotspotLibsRecipe
hotspot-$1-libs:
- +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f lib/CompileLibraries.gmk \
+ +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f lib/CompileLibraries.gmk \
JVM_VARIANT=$1)
endef
$(foreach v, $(JVM_VARIANTS), $(eval $(call DeclareHotspotLibsRecipe,$v)))
hotspot-jsig:
- +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -f lib/CompileLibjsig.gmk)
+ +($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f lib/CompileLibjsig.gmk)
hotspot-ide-project:
+($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk)
@@ -285,7 +285,7 @@
# Jigsaw specific data and analysis targets.
generate-summary:
- +($(CD) $(JDK_TOPDIR)/make && $(MAKE) -f GenerateModuleSummary.gmk)
+ +($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateModuleSummary.gmk)
ALL_TARGETS += generate-summary
@@ -318,7 +318,7 @@
bootcycle-images:
ifneq ($(COMPILE_TYPE), cross)
$(call LogWarn, Boot cycle build step 2: Building a new JDK image using previously built image)
- +$(MAKE) -f $(SRC_ROOT)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \
+ +$(MAKE) $(MAKE_ARGS) -f $(SRC_ROOT)/make/Init.gmk PARALLEL_TARGETS=$(BOOTCYCLE_TARGET) \
JOBS= SPEC=$(dir $(SPEC))bootcycle-spec.gmk main
else
$(call LogWarn, Boot cycle build disabled when cross compiling)
--- a/make/common/MakeBase.gmk Thu Jan 19 10:55:07 2017 -0500
+++ b/make/common/MakeBase.gmk Tue Jan 24 00:30:23 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -862,6 +862,7 @@
( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
( exitcode=$(DOLLAR)? && \
$(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(BUILD_OUTPUT)/%,%,$(strip $1))).log && \
+ $(CP) $(strip $1).cmdline $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(BUILD_OUTPUT)/%,%,$(strip $1))).cmdline && \
exit $(DOLLAR)exitcode ) )
################################################################################
--- a/nashorn/.hgtags Thu Jan 19 10:55:07 2017 -0500
+++ b/nashorn/.hgtags Tue Jan 24 00:30:23 2017 +0100
@@ -385,3 +385,5 @@
c281306d33d83c92e0d870ace385d5f99678d7e7 jdk-9+149
ace1d994bca775d6545a4c874ae73d1dfc9ec18b jdk-9+150
2a0437036a64853334e538044eb68d2df70075fa jdk-9+151
+ddc52e72757086a75a54371e8e7f56a3f89f1e55 jdk-9+152
+19aaaf2d02b7d6986538cd9a8c46901ecb50eebf jdk-9+153
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java Thu Jan 19 10:55:07 2017 -0500
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java Tue Jan 24 00:30:23 2017 +0100
@@ -1032,7 +1032,7 @@
}
final Object key = property.getKey();
- property = iter.next();
+ property = iter.hasNext() ? iter.next() : null;
skipNotEnumerable();
return key;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Thu Jan 19 10:55:07 2017 -0500
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Tue Jan 24 00:30:23 2017 +0100
@@ -28,6 +28,8 @@
import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
@@ -100,7 +102,7 @@
* reparsed from source, or a soft reference to a {@code FunctionNode} for other functions (it is safe
* to be cleared as they can be reparsed).
*/
- private volatile Object cachedAst;
+ private volatile transient Object cachedAst;
/** Token of this function within the source. */
private final long token;
@@ -289,6 +291,9 @@
if (this.source == null && this.installer == null) {
this.source = src;
this.installer = inst;
+ for (final RecompilableScriptFunctionData nested : nestedFunctions.values()) {
+ nested.initTransients(src, inst);
+ }
} else if (this.source != src || !this.installer.isCompatibleWith(inst)) {
// Existing values must be same as those passed as parameters
throw new IllegalArgumentException();
@@ -424,7 +429,7 @@
} else if (lCachedAst instanceof SerializedAst) {
final SerializedAst serializedAst = (SerializedAst)lCachedAst;
// Even so, are we also softly caching the AST?
- final FunctionNode cachedFn = serializedAst.cachedAst.get();
+ final FunctionNode cachedFn = serializedAst.cachedAst == null ? null : serializedAst.cachedAst.get();
if (cachedFn != null) {
// Yes we are - this is fast
return cloneSymbols(cachedFn);
@@ -492,9 +497,11 @@
* we're using this tuple instead to also keep a deserialized AST around in memory to cut down on
* deserialization costs.
*/
- private static class SerializedAst {
+ private static class SerializedAst implements Serializable {
private final byte[] serializedAst;
- private volatile Reference<FunctionNode> cachedAst;
+ private volatile transient Reference<FunctionNode> cachedAst;
+
+ private static final long serialVersionUID = 1L;
SerializedAst(final FunctionNode fn, final Reference<FunctionNode> cachedAst) {
this.serializedAst = AstSerializer.serialize(fn);
@@ -1038,8 +1045,20 @@
return true;
}
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ final Object localCachedAst = cachedAst;
+ out.defaultWriteObject();
+ // We need to persist SerializedAst for split functions as they can't reparse the source code.
+ if (localCachedAst instanceof SerializedAst) {
+ out.writeObject(localCachedAst);
+ } else {
+ out.writeObject(null);
+ }
+ }
+
private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
+ cachedAst = in.readObject();
createLogger();
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/fx/base.js Thu Jan 19 10:55:07 2017 -0500
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/fx/base.js Tue Jan 24 00:30:23 2017 +0100
@@ -108,7 +108,7 @@
}
});
- Files.walkFileTree(rootDirectories[0], new JRTFSWalker());
+ Files.walkFileTree(rootDirectories.toArray()[0], new JRTFSWalker());
})();
LOAD_FX_CLASSES(this, "javafx.base");
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java Thu Jan 19 10:55:07 2017 -0500
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -47,7 +47,7 @@
@SuppressWarnings("javadoc")
public class CodeStoreAndPathTest {
- final String code1 = "var code1; var x = 'Hello Script'; var x1 = 'Hello Script'; "
+ final static String code1 = "var code1; var x = 'Hello Script'; var x1 = 'Hello Script'; "
+ "var x2 = 'Hello Script'; var x3 = 'Hello Script'; "
+ "var x4 = 'Hello Script'; var x5 = 'Hello Script';"
+ "var x6 = 'Hello Script'; var x7 = 'Hello Script'; "
@@ -69,7 +69,7 @@
+ "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';"
+ "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; "
+ "var x10 = 'Hello Script';}";
- final String code2 = "var code2; var x = 'Hello Script'; var x1 = 'Hello Script'; "
+ final static String code2 = "var code2; var x = 'Hello Script'; var x1 = 'Hello Script'; "
+ "var x2 = 'Hello Script'; var x3 = 'Hello Script'; "
+ "var x4 = 'Hello Script'; var x5 = 'Hello Script';"
+ "var x6 = 'Hello Script'; var x7 = 'Hello Script'; "
@@ -92,9 +92,306 @@
+ "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; "
+ "var x10 = 'Hello Script';}";
// Script size < Default minimum size for storing a compiled script class
- final String code3 = "var code3; var x = 'Hello Script'; var x1 = 'Hello Script'; ";
- final String codeCache = "build/nashorn_code_cache";
- final String oldUserDir = System.getProperty("user.dir");
+ final static String code3 = "var code3; var x = 'Hello Script'; var x1 = 'Hello Script'; ";
+ final static String nestedFunctions = "\n" +
+ "(function outer() { \n" +
+ " var map = null; \n" +
+ " (function inner() { \n" +
+ " var object; \n" +
+ " if (map === null) { \n" +
+ " map = (function() { \n" +
+ " var HashMap = Java.type('java.util.HashMap'); \n" +
+ " map = new HashMap(); \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " return map; \n" +
+ " }()); \n" +
+ " } \n" +
+ " object = {}; \n" +
+ " return object; \n" +
+ " })(); \n" +
+ "}()); ";
+ final static String longNestedFunctions = "\n" +
+ "(function outer() { \n" +
+ " var map = null; \n" +
+ " (function inner() { \n" +
+ " var object; \n" +
+ " var HashMap = Java.type('java.util.HashMap'); \n" +
+ " map = new HashMap(); \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address';\n" +
+ " map.name = 'name'; \n" +
+ " map.id = 1234;\n" +
+ " map.basePath = 'basePath'; \n" +
+ " map.extensionPath = 'extension';\n" +
+ " map.address = 'address'; \n" +
+ " object = {}; \n" +
+ " return object; \n" +
+ " })(); \n" +
+ "}()); ";
+ final static String codeCache = "build/nashorn_code_cache";
+ final static String oldUserDir = System.getProperty("user.dir");
private static final String[] ENGINE_OPTIONS_OPT = new String[]{"--persistent-code-cache", "--optimistic-types=true"};
private static final String[] ENGINE_OPTIONS_NOOPT = new String[]{"--persistent-code-cache", "--optimistic-types=false"};
@@ -166,6 +463,28 @@
checkCompiledScripts(stream, 4);
}
+ @Test
+ public void testNestedFunctionStore() throws ScriptException, IOException {
+ System.setProperty("nashorn.persistent.code.cache", codeCache);
+ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(nestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(nestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(nestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(nestedFunctions);
+ }
+
+ @Test
+ public void testSplitFunctionStore() throws ScriptException, IOException {
+ System.setProperty("nashorn.persistent.code.cache", codeCache);
+ System.setProperty("nashorn.compiler.splitter.threshold", "500");
+ final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(longNestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(longNestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(longNestedFunctions);
+ factory.getScriptEngine(ENGINE_OPTIONS_OPT).eval(longNestedFunctions);
+ System.getProperties().remove("nashorn.compiler.splitter.threshold");
+ }
+
private static Path getCodeCachePath(final boolean optimistic) {
final String codeCache = System.getProperty("nashorn.persistent.code.cache");
final Path codeCachePath = FileSystems.getDefault().getPath(codeCache).toAbsolutePath();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/test/PropertyMapTest.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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. 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.internal.runtime.test;
+
+import java.util.Iterator;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for PropertyMap functionality
+ *
+ * @test
+ * @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime
+ * @run testng jdk.nashorn.internal.runtime.test.PropertyMapTest
+ */
+@SuppressWarnings("javadoc")
+public class PropertyMapTest {
+
+ @Test
+ public void propertyMapIteratorTest() {
+ final ScriptObject scriptObject = new ScriptObject(PropertyMap.newMap()) {};
+ Assert.assertFalse(scriptObject.getMap().iterator().hasNext());
+
+ scriptObject.set("a", "a", 0);
+ scriptObject.set("b", 3, 0);
+ // 3 is a valid array key not stored in property map
+ scriptObject.set(3, 1, 0);
+ scriptObject.set(6.5, 1.3, 0);
+ final Iterator<Object> iterator = scriptObject.getMap().iterator();
+
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(iterator.next(), "a");
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(iterator.next(), "b");
+ Assert.assertTrue(iterator.hasNext());
+ Assert.assertEquals(iterator.next(), "6.5");
+ Assert.assertFalse(iterator.hasNext());
+ }
+
+}
--- a/test/failure_handler/src/share/conf/mac.properties Thu Jan 19 10:55:07 2017 -0500
+++ b/test/failure_handler/src/share/conf/mac.properties Tue Jan 24 00:30:23 2017 +0100
@@ -64,7 +64,7 @@
native.core.app=bash
native.core.delimiter=\0
native.core.args=-c\0gcore -o ./core.%p %p || \
- (DevToolsSecurity --status | grep -q enabled && lldb -o 'attach %p' -o 'process save-core core.%p' -o 'detach' -o 'quit')
+ (DevToolsSecurity --status | grep -q enabled && lldb --batch -o 'attach %p' -o 'process save-core core.%p' -o 'detach' -o 'quit')
native.core.params.timeout=3600000
################################################################################
# environment info to gather
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/SecurityTools.java Tue Jan 24 00:30:23 2017 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class SecurityTools {
+
+ public static final String RESPONSE_FILE = "security_tools_response.txt";
+
+ private static ProcessBuilder getProcessBuilder(String tool, List<String> args) {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(tool)
+ .addVMArg("-Duser.language=en")
+ .addVMArg("-Duser.country=US")
+ .addVMArg("-Djava.security.egd=file:/dev/./urandom");
+ for (String arg : args) {
+ if (arg.startsWith("-J")) {
+ launcher.addVMArg(arg.substring(2));
+ } else {
+ launcher.addToolArg(arg);
+ }
+ }
+ String[] cmds = launcher.getCommand();
+ String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ return new ProcessBuilder(cmds);
+ }
+
+ // keytool
+
+ public static OutputAnalyzer keytool(List<String> args)
+ throws Exception {
+
+ ProcessBuilder pb = getProcessBuilder("keytool", args);
+
+ Path p = Paths.get(RESPONSE_FILE);
+ if (!Files.exists(p)) {
+ Files.createFile(p);
+ }
+ pb.redirectInput(ProcessBuilder.Redirect.from(new File(RESPONSE_FILE)));
+
+ try {
+ return ProcessTools.executeProcess(pb);
+ } finally {
+ Files.delete(p);
+ }
+ }
+
+ // Only call this if there is no white space in every argument
+ public static OutputAnalyzer keytool(String args) throws Exception {
+ return keytool(args.split("\\s+"));
+ }
+
+ public static OutputAnalyzer keytool(String... args) throws Exception {
+ return keytool(List.of(args));
+ }
+
+ public static void setResponse(String... responses) throws IOException {
+ String text;
+ if (responses.length > 0) {
+ text = Stream.of(responses).collect(
+ Collectors.joining("\n", "", "\n"));
+ } else {
+ text = "";
+ }
+ Files.write(Paths.get(RESPONSE_FILE), text.getBytes());
+ }
+
+ // jarsigner
+
+ public static OutputAnalyzer jarsigner(List<String> args)
+ throws Exception {
+ return ProcessTools.executeProcess(
+ getProcessBuilder("jarsigner", args));
+ }
+
+ // Only call this if there is no white space in every argument
+ public static OutputAnalyzer jarsigner(String args) throws Exception {
+
+ return jarsigner(args.split("\\s+"));
+ }
+
+ public static OutputAnalyzer jarsigner(String... args) throws Exception {
+ return jarsigner(List.of(args));
+ }
+}
+
--- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java Thu Jan 19 10:55:07 2017 -0500
+++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java Tue Jan 24 00:30:23 2017 +0100
@@ -183,6 +183,23 @@
}
/**
+ * Verify that the stdout and stderr contents of output buffer does not contain the string
+ *
+ * @throws RuntimeException If the string was found
+ */
+ public OutputAnalyzer shouldBeEmpty() {
+ if (!stdout.isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stdout was not empty");
+ }
+ if (!stderr.isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stderr was not empty");
+ }
+ return this;
+ }
+
+ /**
* Verify that the stdout contents of output buffer does not contain the string
*
* @param expectedString String that the buffer should not contain
@@ -365,6 +382,21 @@
return this;
}
+ /**
+ * Verify the exit value of the process
+ *
+ * @param notExpectedExitValue Unexpected exit value from process
+ * @throws RuntimeException If the exit value from the process did match the expected value
+ */
+ public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) {
+ if (getExitValue() == notExpectedExitValue) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("Unexpected to get exit value of ["
+ + notExpectedExitValue + "]\n");
+ }
+ return this;
+ }
+
/**
* Report summary that will help to diagnose the problem