8181087: Module system implementation refresh (6/2017)
Reviewed-by: plevart, mchung
Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Fri Jun 16 09:20:39 2017 -0700
@@ -278,7 +278,6 @@
Java_java_lang_Module_addExports0;
Java_java_lang_Module_addExportsToAll0;
Java_java_lang_Module_addExportsToAllUnnamed0;
- Java_java_lang_Module_addPackage0;
Java_jdk_internal_loader_BootLoader_getSystemPackageLocation;
Java_jdk_internal_loader_BootLoader_getSystemPackageNames;
--- a/jdk/make/src/classes/build/tools/jigsaw/technology-summary.html Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/technology-summary.html Fri Jun 16 09:20:39 2017 -0700
@@ -1,625 +1,534 @@
<html>
<head>
-<title>JDK Technology Summary</title>
+<title>JCP Technologies in JDK 9</title>
<style type="text/css">
table { border: 1px solid black; border-collapse: collapse; }
-tr.se-base { background-color: bisque; }
-tr.se-misc { background-color: lavender; }
-tr.se-ee { background-color: lightgreen; }
+tr.se-base { background-color: yellow; }
+tr.se-misc { background-color: bisque; }
+tr.se-ee { background-color: sandybrown; }
tr.se-ext { background-color: pink; }
-td { font-family: monospace; padding: 4px; border: 1px solid; }
+tr.non-se { background-color: lightsteelblue; }
+td { font-family: monospace; padding: 5px; border: 1px solid; }
+td.agg { background-color: lightgray; }
</style>
</head>
-<h1>JCP Technologies in the Modular JDK</h1>
+<h1>JCP Technologies in JDK 9</h1>
-<p><em>Last updated 2015-03-06 (Added java.datatransfer. Assumes JNLP is modularized, and StAX joins the Java SE Platform.)</em></p>
+<p><em>Last updated 2017-06-08</em></p>
-<p><a href="module-summary.html">JDK Module Summary</a> | Technologies in the <a href="https://docs.oracle.com/javase/8/docs/">Java SE Documentation</a></p>
+<p><a href="module-summary.html">JDK 9 Module Summary</a> | Technologies in the <a href="https://docs.oracle.com/javase/8/docs/">Java SE 8 Documentation</a></p>
<table>
<tr><th>Legend</th></tr>
<tr class="se-base"><td><a href="https://jcp.org/en/jsr/platform?listBy=2&listByType=platform">JCP technology in the Java SE Platform only -- in java.base</a></td></tr>
<tr class="se-misc"><td><a href="https://jcp.org/en/jsr/platform?listBy=2&listByType=platform">JCP technology in the Java SE Platform only -- not in java.base</a></td></tr>
-<tr class="se-ee"><td><a href="https://jcp.org/en/jsr/platform?listBy=3&listByType=platform">JCP technology in the Java SE Platform and the Java EE Platform</a></a></td></tr>
-<tr class="se-ext"><td><a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">JCP technology in the Java SE Platform based on non-JCP standards</a></a></td></tr>
-<tr><td>JCP technology in neither the Java SE or EE Platforms</td></tr>
+<tr class="se-ee"><td><a href="https://jcp.org/en/jsr/platform?listBy=3&listByType=platform">JCP technology in the Java SE Platform derived from the Java EE Platform</a></a></td></tr>
+<tr class="se-ext"><td><a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">JCP technology in the Java SE Platform derived from non-JCP standards</a></a></td></tr>
+<tr class="non-se"><td>JCP technology in neither the Java SE or EE Platforms</td></tr>
</table>
-<p><em>An <strong>upgradeable</strong> module contains JCP technology that is in the Java SE Platform but is not exclusive to the Java SE Platform, i.e., the green and pink technologies. Most upgradeable modules are defined by loaders other than the bootstrap.</em></p>
-
<br/>
<table>
<tr>
+<th>JSR</th>
<th>Technology</th>
-<th>Original JSR</th>
-<th><a href="https://jcp.org/en/procedures/jcp2#DEF">Original Target</a></th>
+<th><a href="https://jcp.org/en/procedures/jcp2_10#3.3.1.2">Evolved By</a></th>
<th>Module</th>
-<th><a href="https://jcp.org/en/procedures/jcp2#2.1.2">Evolved By</a></th>
-<th>History</th>
-<th>Profile/SE</th>
<th>Loader</th>
<th>Upg?</th>
+<th>Notes</th>
+<th>Aggregator</th>
</tr>
-<tr class="se-misc">
-<td>JMX</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=3">3</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.management">java.management</a></td>
+<tr class="se-base">
+<td>---</td>
+<td>Collections, Concurrency, <br/> Core Reflection, I18N, I/O, <br/> JAAS, JCA, JSSE, Math, Net, Text</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
+<td class="agg" rowspan=37><a href="module-summary.html#java.se"/>java.se</a></td>
</tr>
<tr class="se-misc">
-<td>Print Service</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=6">6</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>---</td>
+<td>A11Y, Applet, AWT, Beans, <br/> Image I/O, Java 2D, <br/> Print, Sound, Swing</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>SE</td>
+<td><a href="module-summary.html#java.desktop"/>java.desktop</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>Preferences</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=10">10</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.prefs">java.prefs</a></td>
+<td>---</td>
+<td>Data Transfer</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
+<td><a href="module-summary.html#java.datatransfer"/>java.datatransfer</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>Image I/O</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=15">15</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>---</td>
+<td>JNDI</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>SE</td>
+<td><a href="module-summary.html#java.naming"/>java.naming</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>SASL</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=28">28</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.security.sasl"/>java.security.sasl</a></td>
+<td>---</td>
+<td>RMI</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
+<td><a href="module-summary.html#java.rmi"/>java.rmi</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=3">3</a></td>
+<td>JMX</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>Logging</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=47">47</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.logging">java.logging</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=6">6</a></td>
+<td>Print Service</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
<td>boot</td>
<td>No</td>
-</tr>
-
-<tr class="se-base">
-<td>NIO</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=51">51</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
<td></td>
-<td>1</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr>
-<td>JNLP</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=56">56</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.desktop">java.jnlp</a></td>
-<td>Original JSR</td>
-<td></td>
-<td>N/A</td>
-<td>boot</td>
-<td>No</td>
</tr>
<tr class="se-misc">
-<td>Beans Persistence</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=57">57</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=10">10</a></td>
+<td>Preferences</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>SE</td>
+<td><a href="module-summary.html#java.prefs">java.prefs</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>GSS</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=72">72</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.security.jgss">java.security.jgss</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=15">15</a></td>
+<td>Image I/O</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=28">28</a></td>
+<td>SASL</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.security.sasl"/>java.security.sasl</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>XML Digital Signature</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=105">105</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml.crypto">java.xml.crypto</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=47">47</a></td>
+<td>Logging</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>JDBC Rowset</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=114">114</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.sql.rowset">java.sql.rowset</a></td>
-<td>Original JSR</td>
-<td>Co-evolved with JDBC</td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>JMX Remote</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=160">160</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.management">java.management</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
+<td><a href="module-summary.html#java.logging">java.logging</a></td>
<td>boot</td>
<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>Profiling (Agent)</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.instrument">java.instrument</a></td>
-<td>UJSR for Java SE</td>
<td></td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>Profiling (JMX)</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.management">java.management</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-base">
-<td>Concurrency Utilities</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=166">166</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
-<td>boot</td>
-<td>No</td>
</tr>
<tr class="se-base">
-<td>Annotations</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=51">51</a></td>
+<td>NIO</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=57">57</a></td>
+<td>Beans Persistence</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>StAX</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=173">173</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml">java.xml</a></td>
-<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>2</td>
-<td>boot</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=72">72</a></td>
+<td>GSS</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.security.jgss">java.security.jgss</a></td>
+<td>plat</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>Annotations (Language Model)</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=105">105</a></td>
+<td>XML Digital Signature</td>
<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.xml.crypto">java.xml.crypto</a></td>
+<td>plat</td>
+<td>No</td>
<td></td>
-<td>3</td>
-<td>boot</td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=114">114</a></td>
+<td>JDBC Rowset</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.sql.rowset">java.sql.rowset</a></td>
+<td>plat</td>
<td>No</td>
+<td>Co-developed with JDBC</td>
</tr>
<tr class="se-misc">
-<td>Compiler</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=199">199</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.compiler">java.compiler</a></td>
-<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>3</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=160">160</a></td>
+<td>JMX Remote</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=160">160</a></td>
+<td>JMX Remote (RMI)</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.management.rmi">java.management.rmi</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
+<td>Instrumentation</td> <!-- Profiling (Agent) -->
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.instrument">java.instrument</a></td>
+<td>boot</td>
+<td>No</td>
+<td>Co-developed with JVMTI</td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
+<td>Monitoring & Management</td> <!-- Profiling (JMX) -->
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
</tr>
<tr class="se-base">
-<td>Pack200</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=200">200</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=166">166</a></td>
+<td>Concurrency Utilities</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=173">173</a></td>
+<td>StAX</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>boot</td>
+<td>No</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
</tr>
<tr class="se-base">
-<td>NIO.2</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=203">203</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
+<td>Annotations (Core Reflection)</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>JAXP</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=206">206</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml">java.xml</a></td>
-<td>UJSR for Java SE</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>2</td>
-<td>boot</td>
-<td>No</td>
+<td></td>
</tr>
<tr class="se-misc">
-<td>JDBC</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=221">221</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.sql">java.sql</a></td>
-<td>Original JSR</td>
-<td>Co-evolved with JDBC Rowset</td>
-<td>2</td>
-<td>boot</td>
-<td>No</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
+<td>Annotations (Language Model)</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Co-located with a former Standalone Technology</td>
</tr>
<tr class="se-misc">
-<td>Scripting</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=223">223</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.scripting">java.scripting</a></td>
-<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>1</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr>
-<td>Smart Card I/O</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=268">268</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.smartcardio">java.smartcardio</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=199">199</a></td>
+<td>Compiler</td>
<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>N/A</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>Annotation Processing</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=269">269</a></td>
-<td>Java SE</td>
<td><a href="module-summary.html#java.compiler">java.compiler</a></td>
-<td>Original JSR</td>
+<td>plat</td>
+<td>Yes</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
</tr>
<tr class="se-base">
-<td>InvokeDynamic</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=292">292</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=200">200</a></td>
+<td>Pack200</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-base">
-<td>Type Annotations</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=203">203</a></td>
+<td>NIO.2</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
+<td></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=206">206</a></td>
+<td>JAXP</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>boot</td>
+<td>No</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
</tr>
<tr class="se-misc">
-<td>Type Annotations (Language Model)</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
-<td>boot</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=221">221</a></td>
+<td>JDBC</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.sql">java.sql</a></td>
+<td>plat</td>
<td>No</td>
+<td>Co-developed with JDBC Rowset</td>
</tr>
-<tr class="se-base">
-<td>Date and Time</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=310">310</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=223">223</a></td>
+<td>Scripting</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
-<td>boot</td>
+<td><a href="module-summary.html#java.scripting">java.scripting</a></td>
+<td>plat</td>
<td>No</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+</tr>
+
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=269">269</a></td>
+<td>Annotation Processing</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.compiler">java.compiler</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
</tr>
<tr class="se-base">
-<td>Streams</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=335">335</a></td>
-<td>Java SE</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=292">292</a></td>
+<td>InvokeDynamic</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
<tr class="se-base">
-<td>Collections, Math, I18N, I/O, Net, Reflection</td>
-<td>---</td>
-<td>---</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
+<td>Type Annotations (Core Reflection)</td>
+<td>UJSR for Java SE</td>
<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>1</td>
<td>boot</td>
<td>No</td>
-</tr>
-
-<tr class="se-base">
-<td>JCA, JAAS, JSSE</td>
-<td>---</td>
-<td>---</td>
-<td><a href="module-summary.html#java.base"/>java.base</a></td>
-<td>UJSR for Java SE</td>
<td></td>
-<td>1</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>Applet, AWT, Swing, Java 2D, Beans, A11Y, Sound</td>
-<td>---</td>
-<td>---</td>
-<td><a href="module-summary.html#java.desktop"/>java.desktop</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>SE</td>
-<td>boot</td>
-<td>No</td>
</tr>
<tr class="se-misc">
-<td>Data Transfer</td>
-<td>---</td>
-<td>---</td>
-<td><a href="module-summary.html#java.datatransfer"/>java.datatransfer</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
+<td>Type Annotations (Language Model)</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>SE</td>
-<td>boot</td>
-<td>No</td>
-</tr>
-
-<tr class="se-misc">
-<td>JNDI</td>
-<td>---</td>
-<td>---</td>
-<td><a href="module-summary.html#java.naming"/>java.naming</a></td>
-<td>UJSR for Java SE</td>
-<td></td>
-<td>3</td>
-<td>boot</td>
-<td>No</td>
+<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Co-located with a former Standalone Technology</td>
</tr>
-<tr class="se-misc">
-<td>RMI</td>
-<td>---</td>
-<td>---</td>
-<td><a href="module-summary.html#java.rmi"/>java.rmi</a></td>
+<tr class="se-base">
+<td><a href="https://jcp.org/en/jsr/detail?id=310">310</a></td>
+<td>Date and Time</td>
<td>UJSR for Java SE</td>
-<td></td>
-<td>2</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
<td>boot</td>
<td>No</td>
+<td></td>
</tr>
-<tr class="se-misc">
-<td>JAF</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=925">925</a></td>
-<td>---</td>
-<td><a href="module-summary.html#java.activation">java.activation</a></a></td>
-<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
+<tr class="se-base">
+<td><a href="https://jcp.org/en/jsr/detail?id=335">335</a></td>
+<td>Streams</td>
+<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>boot</td>
+<td>No</td>
+<td></td>
</tr>
<tr class="se-ext">
-<td>RMI-IIOP, IDL</td>
-<td>(OMG)</td>
-<td>---</td>
-<td><a href="module-summary.html#java.corba"/>java.corba</a></td>
+<td>(W3C)</td>
+<td>DOM, SAX</td>
<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>boot</td>
+<td>No</td>
<td>Formerly an <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">Endorsed Standard</a></td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
</tr>
<tr class="se-ext">
-<td>DOM, SAX</td>
-<td>(W3C)</td>
-<td>---</td>
-<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>(OMG)</td>
+<td>RMI-IIOP, IDL</td>
<td>UJSR for Java SE</td>
+<td><a href="module-summary.html#java.corba"/>java.corba</a></td>
+<td>plat</td>
+<td>Yes</td>
<td>Formerly an <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">Endorsed Standard</a></td>
-<td>2</td>
-<td>boot</td>
-<td>No</td>
+<td class="agg" rowspan=7><a href="module-summary.html#java.se.ee"/>java.se.ee</a></td>
+</tr>
+
+<tr class="se-ee">
+<td><a href="https://jcp.org/en/jsr/detail?id=67">67</a></td>
+<td>SAAJ</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (f.k.a. JAXM)</td>
+</tr>
+
+<tr class="se-ee">
+<td><a href="https://jcp.org/en/jsr/detail?id=181">181</a></td>
+<td>Web Services Metadata</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
</tr>
<tr class="se-ee">
-<td>SAAJ</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=67">67</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
-<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (f.k.a. JAXM)</td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
-</tr>
-
-<tr class="se-ee">
-<td>Web Services Metadata</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=181">181</a></td>
-<td>Java EE</td>
-<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td><a href="https://jcp.org/en/jsr/detail?id=222">222</a></td>
+<td>JAXB</td>
<td>Original JSR</td>
-<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>SE</td>
-<td>ext</td>
+<td><a href="module-summary.html#java.xml.bind">java.xml.bind</a></td>
+<td>plat</td>
<td>Yes</td>
-</tr>
-
-<tr class="se-ee">
-<td>JAXB</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=222">222</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml.bind">java.xml.bind</a></td>
-<td>Original JSR</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
</tr>
<tr class="se-ee">
+<td><a href="https://jcp.org/en/jsr/detail?id=224">224</a></td>
<td>JAXWS</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=224">224</a></td>
-<td>Java SE</td>
-<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
<td>Original JSR</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>plat</td>
+<td>Yes</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
</tr>
-<!-- Alex: The Java SE Platform incorporates a cutdown version of the javax.annotation package from the Java EE Platform. -->
+<!-- The Java SE Platform incorporates a smaller version of the javax.annotation package than the Java EE Platform. -->
<tr class="se-ee">
+<td><a href="https://jcp.org/en/jsr/detail?id=250">250</a></td>
<td>Common Annotations</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=250">250</a></td>
-<td>Java SE,EE</td>
+<td>Original JSR</td>
<td><a href="module-summary.html#java.xml.ws.annotation">java.xml.ws.annotation</a></td>
-<td>Original JSR</td>
+<td>plat</td>
+<td>Yes</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>SE</td>
-<td>ext</td>
+</tr>
+
+<!-- The Java SE Platform incorporates a smaller version of the javax.transaction package than the Java EE Platform. -->
+<tr class="se-ee">
+<td><a href="https://jcp.org/en/jsr/detail?id=907">907</a></td>
+<td>JTA (non-XA)</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.transaction">java.transaction</a></td>
+<td>plat</td>
<td>Yes</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
</tr>
-<!-- Alex: The Java SE Platform incorporates a cutdown version of the javax.transaction package from the Java EE Platform. -->
+<!-- The Java SE Platform incorporates the same version of the javax.transaction.xa package as the Java EE Platform. -->
<tr class="se-ee">
-<td>JTA (non-XA)</td>
<td><a href="https://jcp.org/en/jsr/detail?id=907">907</a></td>
-<td>---</td>
-<td><a href="module-summary.html#java.transaction">java.transaction</a></td>
+<td>JTA (XA)</td>
<td>Original JSR</td>
+<td><a href="module-summary.html#java.sql"/>java.sql</a></td>
+<td>plat</td>
+<td>No</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>SE</td>
-<td>ext</td>
-<td>Yes</td>
+<td class="agg"><a href="module-summary.html#java.se"/>java.se</a></td>
</tr>
-<!-- Alex: The Java SE Platform incorporates the same version of the javax.transaction.xa package as the Java EE Platform. -->
-<tr class="se-ee">
-<td>JTA (XA)</td>
-<td><a href="https://jcp.org/en/jsr/detail?id=907">907</a></td>
-<td>---</td>
-<td><a href="module-summary.html#java.sql"/>java.sql</a></td>
+<tr class="se-misc">
+<td><a href="https://jcp.org/en/jsr/detail?id=925">925</a></td>
+<td>JAF</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.activation">java.activation</a></a></td>
+<td>plat</td>
+<td>Yes</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td class="agg"><a href="module-summary.html#java.se.ee"/>java.se.ee</a></td>
+</tr>
+
+<tr class="non-se">
+<td><a href="https://jcp.org/en/jsr/detail?id=56">56</a></td>
+<td>JNLP</td>
<td>Original JSR</td>
+<td><a href="module-summary.html#java.desktop">java.jnlp</a></td>
+<td>plat</td>
+<td>Yes</td>
+<td></td>
+<td class="agg" rowspan=2>None</td>
+</tr>
+
+<tr class="non-se">
+<td><a href="https://jcp.org/en/jsr/detail?id=268">268</a></td>
+<td>Smart Card I/O</td>
+<td>Original JSR</td>
+<td><a href="module-summary.html#java.smartcardio">java.smartcardio</a></td>
+<td>plat</td>
+<td>No</td>
<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
-<td>2</td>
-<td>boot</td>
-<td>No</td>
</tr>
</table>
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Fri Jun 16 09:20:39 2017 -0700
@@ -50,6 +50,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -2067,25 +2068,6 @@
}
/**
- * Returns a {@code Method} object that reflects the specified public
- * member method of the class or interface represented by this
- * {@code Class} object.
- *
- * @param name the name of the method
- * @param parameterTypes the list of parameters
- * @return the {@code Method} object that matches the specified
- * {@code name} and {@code parameterTypes}; {@code null}
- * if the method is not found or the name is
- * "<init>"or "<clinit>".
- */
- Method getMethodOrNull(String name, Class<?>... parameterTypes) {
- Objects.requireNonNull(name);
- Method method = getMethod0(name, parameterTypes);
- return method == null ? null : getReflectionFactory().copyMethod(method);
- }
-
-
- /**
* Returns a {@code Constructor} object that reflects the specified
* public constructor of the class represented by this {@code Class}
* object. The {@code parameterTypes} parameter is an array of
@@ -2225,7 +2207,6 @@
/**
- *
* Returns an array containing {@code Method} objects reflecting all the
* declared methods of the class or interface represented by this {@code
* Class} object, including public, protected, default (package)
@@ -2453,6 +2434,30 @@
return getReflectionFactory().copyMethod(method);
}
+ /**
+ * Returns the list of {@code Method} objects for the declared public
+ * methods of this class or interface that have the specified method name
+ * and parameter types.
+ *
+ * @param name the name of the method
+ * @param parameterTypes the parameter array
+ * @return the list of {@code Method} objects for the public methods of
+ * this class matching the specified name and parameters
+ */
+ List<Method> getDeclaredPublicMethods(String name, Class<?>... parameterTypes) {
+ Method[] methods = privateGetDeclaredMethods(/* publicOnly */ true);
+ ReflectionFactory factory = getReflectionFactory();
+ List<Method> result = new ArrayList<>();
+ for (Method method : methods) {
+ if (method.getName().equals(name)
+ && Arrays.equals(
+ factory.getExecutableSharedParameterTypes(method),
+ parameterTypes)) {
+ result.add(factory.copyMethod(method));
+ }
+ }
+ return result;
+ }
/**
* Returns a {@code Constructor} object that reflects the specified
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Fri Jun 16 09:20:39 2017 -0700
@@ -93,12 +93,20 @@
* <p> Class loaders may typically be used by security managers to indicate
* security domains.
*
+ * <p> In addition to loading classes, a class loader is also responsible for
+ * locating resources. A resource is some data (a "{@code .class}" file,
+ * configuration data, or an image for example) that is identified with an
+ * abstract '/'-separated path name. Resources are typically packaged with an
+ * application or library so that they can be located by code in the
+ * application or library. In some cases, the resources are included so that
+ * they can be located by other libraries.
+ *
* <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 {@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.
+ * associated parent class loader. When requested to find a class or
+ * resource, a {@code ClassLoader} instance will usually delegate the search
+ * for the class or resource to its parent class loader before attempting to
+ * find the class or resource itself.
*
* <p> Class loaders that support concurrent loading of classes are known as
* <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
@@ -129,11 +137,13 @@
* classes and JDK-specific run-time classes that are defined by the
* platform class loader or its ancestors.
* <p> To allow for upgrading/overriding of modules defined to the platform
- * class loader, and where classes in the upgraded version link to
- * classes in modules defined to the application class loader, the
- * platform class loader may delegate to the application class loader.
- * In other words, classes in named modules defined to the application
- * class loader may be visible to the platform class loader. </li>
+ * class loader, and where upgraded modules read modules defined to class
+ * loaders other than the platform class loader and its ancestors, then
+ * the platform class loader may have to delegate to other class loaders,
+ * the application class loader for example.
+ * In other words, classes in named modules defined to class loaders
+ * other than the platform class loader and its ancestors may be visible
+ * to the platform class loader. </li>
* <li><p>{@linkplain #getSystemClassLoader() System class loader}.
* It is also known as <em>application class loader</em> and is distinct
* from the platform class loader.
@@ -498,7 +508,7 @@
*
* <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>
+ * loader built into the virtual machine is used, instead. </p></li>
*
* <li><p> Invoke the {@link #findClass(String)} method to find the
* class. </p></li>
@@ -681,8 +691,9 @@
* 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 loadClass} method after checking the
- * parent class loader for the requested class. The default implementation
- * throws a {@code ClassNotFoundException}.
+ * parent class loader for the requested class.
+ *
+ * @implSpec The default implementation throws {@code ClassNotFoundException}.
*
* @param name
* The <a href="#name">binary name</a> of the class
@@ -1127,8 +1138,9 @@
putIfAbsent(pname, (certs == null? nocerts:certs));
}
if (pcerts != null && !compareCerts(pcerts, certs)) {
- throw new SecurityException("class \""+ name +
- "\"'s signer information does not match signer information of other classes in the same package");
+ throw new SecurityException("class \"" + name
+ + "\"'s signer information does not match signer information"
+ + " of other classes in the same package");
}
}
@@ -1329,12 +1341,7 @@
* that is independent of the location of the code.
*
* <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 {@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>
+ * identifies the resource. </p>
*
* <p> Resources in named modules are subject to the encapsulation rules
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
@@ -1344,6 +1351,11 @@
* opened} unconditionally (even if the caller of this method is in the
* same module as the resource). </p>
*
+ * @implSpec The default implementation will first search the parent class
+ * loader for the resource; if the parent is {@code null} the path of the
+ * class loader built into the virtual machine is searched. If not found,
+ * this method will invoke {@link #findResource(String)} to find the resource.
+ *
* @apiNote Where several modules are defined to the same class loader,
* and where more than one module contains a resource with the given name,
* then the ordering that modules are searched is not specified and may be
@@ -1387,10 +1399,7 @@
* that is independent of the location of the code.
*
* <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
- * for {@link #getResource(String)}. </p>
+ * identifies the resource. </p>
*
* <p> Resources in named modules are subject to the encapsulation rules
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
@@ -1398,7 +1407,15 @@
* name ending with "{@code .class}", this method will only find resources in
* packages of named modules when the package is {@link Module#isOpen(String)
* opened} unconditionally (even if the caller of this method is in the
- * same module as the resource).</p>
+ * same module as the resource). </p>
+ *
+ * @implSpec The default implementation will first search the parent class
+ * loader for the resource; if the parent is {@code null} the path of the
+ * class loader built into the virtual machine is searched. It then
+ * invokes {@link #findResources(String)} to find the resources with the
+ * name in this class loader. It returns an enumeration whose elements
+ * are the URLs found by searching the parent class loader followed by
+ * the elements found with {@code findResources}.
*
* @apiNote Where several modules are defined to the same class loader,
* and where more than one module contains a resource with the given name,
@@ -1424,8 +1441,6 @@
* If I/O errors occur
* @throws NullPointerException If {@code name} is {@code null}
*
- * @see #findResources(String)
- *
* @since 1.2
* @revised 9
* @spec JPMS
@@ -1453,9 +1468,6 @@
* <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
- * <p> The search order is described in the documentation for {@link
- * #getResource(String)}.
- *
* <p> The resources will be located when the returned stream is evaluated.
* If the evaluation results in an {@code IOException} then the I/O
* exception is wrapped in an {@link UncheckedIOException} that is then
@@ -1469,6 +1481,10 @@
* opened} unconditionally (even if the caller of this method is in the
* same module as the resource). </p>
*
+ * @implSpec The default implementation invokes {@link #getResources(String)
+ * getResources} to find all the resources with the given name and returns
+ * a stream with the elements in the enumeration as the source.
+ *
* @apiNote When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResource(java.lang.String) getResource(String)} method. This should
@@ -1486,8 +1502,6 @@
*
* @throws NullPointerException If {@code name} is {@code null}
*
- * @see #findResources(String)
- *
* @since 9
*/
public Stream<URL> resources(String name) {
@@ -1506,7 +1520,7 @@
/**
* Finds the resource with the given name. Class loader implementations
- * should override this method to specify where to find resources.
+ * should override this method.
*
* <p> For resources in named modules then the method must implement the
* rules for encapsulation specified in the {@code Module} {@link
@@ -1515,6 +1529,8 @@
* modules unless the package is {@link Module#isOpen(String) opened}
* unconditionally. </p>
*
+ * @implSpec The default implementation returns {@code null}.
+ *
* @param name
* The resource name
*
@@ -1535,8 +1551,7 @@
/**
* 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.
+ * implementations should override this method.
*
* <p> For resources in named modules then the method must implement the
* rules for encapsulation specified in the {@code Module} {@link
@@ -1545,6 +1560,9 @@
* modules unless the package is {@link Module#isOpen(String) opened}
* unconditionally. </p>
*
+ * @implSpec The default implementation returns an enumeration that
+ * contains no elements.
+ *
* @param name
* The resource name
*
@@ -1899,7 +1917,8 @@
// the system class loader is the built-in app class loader during startup
return getBuiltinAppClassLoader();
case 3:
- throw new InternalError("getSystemClassLoader should only be called after VM booted");
+ String msg = "getSystemClassLoader should only be called after VM booted";
+ throw new InternalError(msg);
case 4:
// system fully initialized
assert VM.isBooted() && scl != null;
--- a/jdk/src/java.base/share/classes/java/lang/LayerInstantiationException.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LayerInstantiationException.java Fri Jun 16 09:20:39 2017 -0700
@@ -63,8 +63,8 @@
}
/**
- * Constructs a {@code FindException} with the given detail message
- * and cause.
+ * Constructs a {@code LayerInstantiationException} with the given detail
+ * message and cause.
*
* @param msg
* The detail message; can be {@code null}
@@ -74,6 +74,5 @@
public LayerInstantiationException(String msg, Throwable cause) {
super(msg, cause);
}
-
}
--- a/jdk/src/java.base/share/classes/java/lang/Module.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Module.java Fri Jun 16 09:20:39 2017 -0700
@@ -43,6 +43,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -55,8 +56,10 @@
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
+import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.module.ServicesCatalog;
import jdk.internal.module.Resources;
@@ -162,7 +165,6 @@
}
-
/**
* Returns {@code true} if this module is a named module.
*
@@ -249,12 +251,10 @@
// special Module to mean "all unnamed modules"
private static final Module ALL_UNNAMED_MODULE = new Module(null);
+ private static final Set<Module> ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
// special Module to mean "everyone"
private static final Module EVERYONE_MODULE = new Module(null);
-
- // set contains EVERYONE_MODULE, used when a package is opened or
- // exported unconditionally
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
@@ -534,12 +534,12 @@
return true;
// all packages are exported/open to self
- if (other == this && containsPackage(pn))
+ if (other == this && descriptor.packages().contains(pn))
return true;
// all packages in open and automatic modules are open
if (descriptor.isOpen() || descriptor.isAutomatic())
- return containsPackage(pn);
+ return descriptor.packages().contains(pn);
// exported/opened via module declaration/descriptor
if (isStaticallyExportedOrOpen(pn, other, open))
@@ -555,42 +555,48 @@
/**
* Returns {@code true} if this module exports or opens a package to
- * the given module via its module declaration.
+ * the given module via its module declaration or CLI options.
*/
private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
- // package is open to everyone or <other>
+ // test if package is open to everyone or <other>
Map<String, Set<Module>> openPackages = this.openPackages;
- if (openPackages != null) {
- Set<Module> targets = openPackages.get(pn);
- if (targets != null) {
- if (targets.contains(EVERYONE_MODULE))
- return true;
- if (other != EVERYONE_MODULE && targets.contains(other))
- return true;
- }
+ if (openPackages != null && allows(openPackages.get(pn), other)) {
+ return true;
}
if (!open) {
- // package is exported to everyone or <other>
+ // test package is exported to everyone or <other>
Map<String, Set<Module>> exportedPackages = this.exportedPackages;
- if (exportedPackages != null) {
- Set<Module> targets = exportedPackages.get(pn);
- if (targets != null) {
- if (targets.contains(EVERYONE_MODULE))
- return true;
- if (other != EVERYONE_MODULE && targets.contains(other))
- return true;
- }
+ if (exportedPackages != null && allows(exportedPackages.get(pn), other)) {
+ return true;
}
}
return false;
}
+ /**
+ * Returns {@code true} if targets is non-null and contains EVERYONE_MODULE
+ * or the given module. Also returns true if the given module is an unnamed
+ * module and targets contains ALL_UNNAMED_MODULE.
+ */
+ private boolean allows(Set<Module> targets, Module module) {
+ if (targets != null) {
+ if (targets.contains(EVERYONE_MODULE))
+ return true;
+ if (module != EVERYONE_MODULE) {
+ if (targets.contains(module))
+ return true;
+ if (!module.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
+ return true;
+ }
+ }
+ return false;
+ }
/**
- * Returns {@code true} if this module reflectively exports or opens given
- * package package to the given module.
+ * Returns {@code true} if this module reflectively exports or opens the
+ * given package to the given module.
*/
private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
// exported or open to all modules
@@ -632,6 +638,22 @@
return false;
}
+ /**
+ * Returns {@code true} if this module reflectively exports the
+ * given package to the given module.
+ */
+ boolean isReflectivelyExported(String pn, Module other) {
+ return isReflectivelyExportedOrOpen(pn, other, false);
+ }
+
+ /**
+ * Returns {@code true} if this module reflectively opens the
+ * given package to the given module.
+ */
+ boolean isReflectivelyOpened(String pn, Module other) {
+ return isReflectivelyExportedOrOpen(pn, other, true);
+ }
+
/**
* If the caller's module is this module then update this module to export
@@ -800,7 +822,7 @@
}
/**
- * Updates this module to export a package to all unnamed modules.
+ * Updates this module to open a package to all unnamed modules.
*
* @apiNote Used by the --add-opens command line option.
*/
@@ -808,7 +830,6 @@
implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
}
-
/**
* Updates a module to export or open a module to another module.
*
@@ -825,12 +846,31 @@
if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
return;
- // nothing to do if already exported/open to other
- if (implIsExportedOrOpen(pn, other, open))
- return;
+ // check if the package is already exported/open to other
+ if (implIsExportedOrOpen(pn, other, open)) {
+
+ // if the package is exported/open for illegal access then we need
+ // to record that it has also been exported/opened reflectively so
+ // that the IllegalAccessLogger doesn't emit a warning.
+ boolean needToAdd = false;
+ if (!other.isNamed()) {
+ IllegalAccessLogger l = IllegalAccessLogger.illegalAccessLogger();
+ if (l != null) {
+ if (open) {
+ needToAdd = l.isOpenForIllegalAccess(this, pn);
+ } else {
+ needToAdd = l.isExportedForIllegalAccess(this, pn);
+ }
+ }
+ }
+ if (!needToAdd) {
+ // nothing to do
+ return;
+ }
+ }
// can only export a package in the module
- if (!containsPackage(pn)) {
+ if (!descriptor.packages().contains(pn)) {
throw new IllegalArgumentException("package " + pn
+ " not in contents");
}
@@ -850,7 +890,6 @@
Map<String, Boolean> map = reflectivelyExports
.computeIfAbsent(this, other,
(m1, m2) -> new ConcurrentHashMap<>());
-
if (open) {
map.put(pn, Boolean.TRUE); // may need to promote from FALSE to TRUE
} else {
@@ -858,6 +897,38 @@
}
}
+ /**
+ * Updates a module to open all packages returned by the given iterator to
+ * all unnamed modules.
+ *
+ * @apiNote Used during startup to open packages for illegal access.
+ */
+ void implAddOpensToAllUnnamed(Iterator<String> iterator) {
+ if (jdk.internal.misc.VM.isModuleSystemInited()) {
+ throw new IllegalStateException("Module system already initialized");
+ }
+
+ // replace this module's openPackages map with a new map that opens
+ // the packages to all unnamed modules.
+ Map<String, Set<Module>> openPackages = this.openPackages;
+ if (openPackages == null) {
+ openPackages = new HashMap<>();
+ } else {
+ openPackages = new HashMap<>(openPackages);
+ }
+ while (iterator.hasNext()) {
+ String pn = iterator.next();
+ Set<Module> prev = openPackages.putIfAbsent(pn, ALL_UNNAMED_MODULE_SET);
+ if (prev != null) {
+ prev.add(ALL_UNNAMED_MODULE);
+ }
+
+ // update VM to export the package
+ addExportsToAllUnnamed0(this, pn);
+ }
+ this.openPackages = openPackages;
+ }
+
// -- services --
@@ -947,19 +1018,6 @@
// -- packages --
- // Additional packages that are added to the module at run-time.
- private volatile Map<String, Boolean> extraPackages;
-
- private boolean containsPackage(String pn) {
- if (descriptor.packages().contains(pn))
- return true;
- Map<String, Boolean> extraPackages = this.extraPackages;
- if (extraPackages != null && extraPackages.containsKey(pn))
- return true;
- return false;
- }
-
-
/**
* Returns the set of package names for the packages in this module.
*
@@ -974,89 +1032,19 @@
*/
public Set<String> getPackages() {
if (isNamed()) {
-
- Set<String> packages = descriptor.packages();
- Map<String, Boolean> extraPackages = this.extraPackages;
- if (extraPackages == null) {
- return packages;
- } else {
- return Stream.concat(packages.stream(),
- extraPackages.keySet().stream())
- .collect(Collectors.toSet());
- }
-
+ return descriptor.packages();
} else {
// unnamed module
Stream<Package> packages;
if (loader == null) {
packages = BootLoader.packages();
} else {
- packages = SharedSecrets.getJavaLangAccess().packages(loader);
+ packages = loader.packages();
}
return packages.map(Package::getName).collect(Collectors.toSet());
}
}
- /**
- * Add a package to this module without notifying the VM.
- *
- * @apiNote This method is VM white-box testing.
- */
- void implAddPackageNoSync(String pn) {
- implAddPackage(pn.replace('/', '.'), false);
- }
-
- /**
- * Add a package to this module.
- *
- * If {@code syncVM} is {@code true} then the VM is notified. This method is
- * a no-op if this is an unnamed module or the module already contains the
- * package.
- *
- * @throws IllegalArgumentException if the package name is not legal
- * @throws IllegalStateException if the package is defined to another module
- */
- private void implAddPackage(String pn, boolean syncVM) {
- // no-op if unnamed module
- if (!isNamed())
- return;
-
- // no-op if module contains the package
- if (containsPackage(pn))
- return;
-
- // check package name is legal for named modules
- if (pn.isEmpty())
- throw new IllegalArgumentException("Cannot add <unnamed> package");
- for (int i=0; i<pn.length(); i++) {
- char c = pn.charAt(i);
- if (c == '/' || c == ';' || c == '[') {
- throw new IllegalArgumentException("Illegal character: " + c);
- }
- }
-
- // create extraPackages if needed
- Map<String, Boolean> extraPackages = this.extraPackages;
- if (extraPackages == null) {
- synchronized (this) {
- extraPackages = this.extraPackages;
- if (extraPackages == null)
- this.extraPackages = extraPackages = new ConcurrentHashMap<>();
- }
- }
-
- // update VM first in case it fails. This is a no-op if another thread
- // beats us to add the package first
- if (syncVM) {
- // throws IllegalStateException if defined to another module
- addPackage0(this, pn);
- if (descriptor.isOpen() || descriptor.isAutomatic()) {
- addExportsToAll0(this, pn);
- }
- }
- extraPackages.putIfAbsent(pn, Boolean.TRUE);
- }
-
// -- creating Module objects --
@@ -1075,18 +1063,22 @@
Map<String, Module> nameToModule = new HashMap<>();
Map<String, ClassLoader> moduleToLoader = new HashMap<>();
- boolean isBootLayer = (ModuleLayer.boot() == null);
Set<ClassLoader> loaders = new HashSet<>();
+ boolean hasPlatformModules = false;
// map each module to a class loader
for (ResolvedModule resolvedModule : cf.modules()) {
String name = resolvedModule.name();
ClassLoader loader = clf.apply(name);
- if (loader != null) {
- moduleToLoader.put(name, loader);
+ moduleToLoader.put(name, loader);
+ if (loader == null || loader == ClassLoaders.platformClassLoader()) {
+ if (!(clf instanceof ModuleLoaderMap.Mapper)) {
+ throw new IllegalArgumentException("loader can't be 'null'"
+ + " or the platform class loader");
+ }
+ hasPlatformModules = true;
+ } else {
loaders.add(loader);
- } else if (!(clf instanceof ModuleLoaderMap.Mapper)) {
- throw new IllegalArgumentException("loader can't be 'null'");
}
}
@@ -1098,7 +1090,7 @@
URI uri = mref.location().orElse(null);
ClassLoader loader = moduleToLoader.get(resolvedModule.name());
Module m;
- if (loader == null && isBootLayer && name.equals("java.base")) {
+ if (loader == null && name.equals("java.base")) {
// java.base is already defined to the VM
m = Object.class.getModule();
} else {
@@ -1157,8 +1149,12 @@
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
}
- // register the modules in the boot layer
- if (isBootLayer) {
+ // if there are modules defined to the boot or platform class loaders
+ // then register the modules in the class loader's services catalog
+ if (hasPlatformModules) {
+ ClassLoader pcl = ClassLoaders.platformClassLoader();
+ ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
+ ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
ModuleDescriptor descriptor = mref.descriptor();
@@ -1166,13 +1162,11 @@
String name = descriptor.name();
Module m = nameToModule.get(name);
ClassLoader loader = moduleToLoader.get(name);
- ServicesCatalog catalog;
if (loader == null) {
- catalog = BootLoader.getServicesCatalog();
- } else {
- catalog = ServicesCatalog.getServicesCatalog(loader);
+ bootCatalog.register(m);
+ } else if (loader == pcl) {
+ pclCatalog.register(m);
}
- catalog.register(m);
}
}
}
@@ -1587,7 +1581,4 @@
// JVM_AddModuleExportsToAllUnnamed
private static native void addExportsToAllUnnamed0(Module from, String pn);
-
- // JVM_AddModulePackage
- private static native void addPackage0(Module m, String pn);
}
--- a/jdk/src/java.base/share/classes/java/lang/ModuleLayer.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ModuleLayer.java Fri Jun 16 09:20:39 2017 -0700
@@ -245,6 +245,32 @@
}
/**
+ * Updates module {@code source} in the layer to export a package to
+ * module {@code target}. This method is a no-op if {@code source}
+ * already exports the package to at least {@code target}.
+ *
+ * @param source
+ * The source module
+ * @param pn
+ * The package name
+ * @param target
+ * The target module
+ *
+ * @return This controller
+ *
+ * @throws IllegalArgumentException
+ * If {@code source} is not in the module layer or the package
+ * is not in the source module
+ *
+ * @see Module#addExports
+ */
+ public Controller addExports(Module source, String pn, Module target) {
+ ensureInLayer(source);
+ source.implAddExports(pn, target);
+ return this;
+ }
+
+ /**
* Updates module {@code source} in the layer to open a package to
* module {@code target}. This method is a no-op if {@code source}
* already opens the package to at least {@code target}.
@@ -254,7 +280,7 @@
* @param pn
* The package name
* @param target
- * The target module to read
+ * The target module
*
* @return This controller
*
@@ -397,7 +423,7 @@
* class loader and defines all modules to that class loader.
*
* <p> The class loader created by this method implements <em>direct
- * delegation</em> when loading types from modules. When its {@link
+ * delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. This may be a module in this layer and hence defined to the same
@@ -408,6 +434,12 @@
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
*
+ * <p> The class loader created by this method locates resources
+ * ({@link ClassLoader#getResource(String) getResource}, {@link
+ * ClassLoader#getResources(String) getResources}, and other resource
+ * methods) in all modules in the layer before searching the parent class
+ * loader. </p>
+ *
* <p> Attempting to create a layer with all modules defined to the same
* class loader can fail for the following reasons:
*
@@ -417,8 +449,8 @@
* configuration have the same package. </p></li>
*
* <li><p> <em>Split delegation</em>: The resulting class loader would
- * need to delegate to more than one class loader in order to load types
- * in a specific package. </p></li>
+ * need to delegate to more than one class loader in order to load
+ * classes in a specific package. </p></li>
*
* </ul>
*
@@ -481,7 +513,7 @@
* class loader.
*
* <p> The class loaders created by this method implement <em>direct
- * delegation</em> when loading types from modules. When {@link
+ * delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. The package may be in the module defined to the class loader.
@@ -489,9 +521,15 @@
* module defined to the class loader. It may be in a package exported by a
* module in a parent layer. The class loader delegates to the class loader
* of the module, throwing {@code ClassNotFoundException} if not found by
- * that class loader.
- * When {@code loadClass} is invoked to load classes that do not map to a
- * module then it delegates to the parent class loader. </p>
+ * that class loader. When {@code loadClass} is invoked to load a class
+ * that does not map to a module then it delegates to the parent class
+ * loader. </p>
+ *
+ * <p> The class loaders created by this method locate resources
+ * ({@link ClassLoader#getResource(String) getResource}, {@link
+ * ClassLoader#getResources(String) getResources}, and other resource
+ * methods) in the module defined to the class loader before searching
+ * the parent class loader. </p>
*
* <p> If there is a security manager then the class loaders created by
* this method will load classes and resources with privileges that are
@@ -576,10 +614,9 @@
* <p> In addition, a layer cannot be created if the configuration contains
* a module named "{@code java.base}", a configuration contains a module
* with a package named "{@code java}" or a package name starting with
- * "{@code java.}" and the module is mapped to a class loader other than
- * the {@link ClassLoader#getPlatformClassLoader() platform class loader},
- * or the function to map a module name to a class loader returns
- * {@code null}. </p>
+ * "{@code java.}", or the function to map a module name to a class loader
+ * returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
+ * platform class loader}. </p>
*
* <p> If the function to map a module name to class loader throws an error
* or runtime exception then it is propagated to the caller of this method.
--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Fri Jun 16 09:20:39 2017 -0700
@@ -47,6 +47,8 @@
import java.security.PrivilegedAction;
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
@@ -2067,8 +2069,8 @@
private static void setJavaLangAccess() {
// Allow privileged classes outside of java.lang
SharedSecrets.setJavaLangAccess(new JavaLangAccess() {
- public Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes) {
- return klass.getMethodOrNull(name, parameterTypes);
+ public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
+ return klass.getDeclaredPublicMethods(name, parameterTypes);
}
public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
return klass.getConstantPool();
@@ -2092,7 +2094,7 @@
return Class.getExecutableTypeAnnotationBytes(executable);
}
public <E extends Enum<E>>
- E[] getEnumConstantsShared(Class<E> klass) {
+ E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockedOn(Thread t, Interruptible b) {
@@ -2120,9 +2122,6 @@
public Class<?> findBootstrapClassOrNull(ClassLoader cl, String name) {
return cl.findBootstrapClassOrNull(name);
}
- public Stream<Package> packages(ClassLoader cl) {
- return cl.packages();
- }
public Package definePackage(ClassLoader cl, String name, Module module) {
return cl.definePackage(name, module);
}
@@ -2161,9 +2160,18 @@
public void addOpensToAllUnnamed(Module m, String pn) {
m.implAddOpensToAllUnnamed(pn);
}
+ public void addOpensToAllUnnamed(Module m, Iterator<String> packages) {
+ m.implAddOpensToAllUnnamed(packages);
+ }
public void addUses(Module m, Class<?> service) {
m.implAddUses(service);
}
+ public boolean isReflectivelyExported(Module m, String pn, Module other) {
+ return m.isReflectivelyExported(pn, other);
+ }
+ public boolean isReflectivelyOpened(Module m, String pn, Module other) {
+ return m.isReflectivelyOpened(pn, other);
+ }
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
return layer.getServicesCatalog();
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Jun 16 09:20:39 2017 -0700
@@ -212,7 +212,7 @@
if (!callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
- logger.logIfOpenedByBackdoor(lookup, targetClass);
+ logger.logIfOpenedForIllegalAccess(lookup, targetClass);
}
}
return new Lookup(targetClass);
--- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Fri Jun 16 09:20:39 2017 -0700
@@ -43,11 +43,10 @@
/**
* A configuration that is the result of <a href="package-summary.html#resolution">
- * resolution</a> or resolution with <a href="package-summary.html#servicebinding">
- * service binding</a>.
+ * resolution</a> or resolution with <a href="#service-binding">service binding</a>.
*
* <p> A configuration encapsulates the <em>readability graph</em> that is the
- * output of resolution. A readability graph is a directed graph where the nodes
+ * output of resolution. A readability graph is a directed graph whose vertices
* are of type {@link ResolvedModule} and the edges represent the readability
* amongst the modules. {@code Configuration} defines the {@link #modules()
* modules()} method to get the set of resolved modules in the graph. {@code
@@ -176,8 +175,8 @@
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
- * If any of the post-resolution consistency checks specified by
- * the static {@code resolve} method fail
+ * If resolution fails any of the consistency checks specified by
+ * the static {@code resolve} method
* @throws SecurityException
* If locating a module is denied by the security manager
*/
@@ -219,8 +218,8 @@
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
- * If any of the post-resolution consistency checks specified by
- * the static {@code resolve} method fail
+ * If resolution fails any of the consistency checks specified by
+ * the static {@code resolve} method
* @throws SecurityException
* If locating a module is denied by the security manager
*/
@@ -234,7 +233,7 @@
/**
* Resolves a collection of root modules, with service binding, and with
- * the empty configuration as its parent. The post resolution checks
+ * the empty configuration as its parent. The consistency checks
* are optionally run.
*
* This method is used to create the configuration for the boot layer.
@@ -264,10 +263,9 @@
* or dependences that are located in a parent configuration are resolved
* no further and are not included in the resulting configuration. </p>
*
- * <p> When all modules have been resolved then the resulting dependency
- * graph is checked to ensure that it does not contain cycles. A
- * readability graph is constructed, and in conjunction with the module
- * exports and service use, checked for consistency. </p>
+ * <p> When all modules have been enumerated then a readability graph
+ * is computed, and in conjunction with the module exports and service use,
+ * checked for consistency. </p>
*
* <p> Resolution may fail with {@code FindException} for the following
* <em>observability-related</em> reasons: </p>
@@ -284,8 +282,8 @@
*
* </ul>
*
- * <p> Post-resolution consistency checks may fail with {@code
- * ResolutionException} for the following reasons: </p>
+ * <p> Resolution may fail with {@code ResolutionException} if any of the
+ * following consistency checks fail: </p>
*
* <ul>
*
@@ -329,9 +327,11 @@
* root modules
*
* @throws FindException
- * If resolution fails for an observability-related reason
+ * If resolution fails for any of observability-related reasons
+ * specified above
* @throws ResolutionException
- * If a post-resolution consistency checks fails
+ * If resolution fails for any of the consistency checks specified
+ * above
* @throws IllegalArgumentException
* If the list of parents is empty, or the list has two or more
* parents with modules for different target operating systems,
@@ -368,11 +368,11 @@
* resolve} except that the graph of resolved modules is augmented
* with modules induced by the service-use dependence relation. </p>
*
- * <p> More specifically, the root modules are resolved as if by calling
- * {@code resolve}. The resolved modules, and all modules in the
- * parent configurations, with {@link ModuleDescriptor#uses() service
- * dependences} are then examined. All modules found by the given module
- * finders that {@link ModuleDescriptor#provides() provide} an
+ * <p id="service-binding"> More specifically, the root modules are
+ * resolved as if by calling {@code resolve}. The resolved modules, and
+ * all modules in the parent configurations, with {@link ModuleDescriptor#uses()
+ * service dependences} are then examined. All modules found by the given
+ * module finders that {@link ModuleDescriptor#provides() provide} an
* implementation of one or more of the service types are added to the
* module graph and then resolved as if by calling the {@code
* resolve} method. Adding modules to the module graph may introduce new
@@ -402,8 +402,8 @@
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
- * If any of the post-resolution consistency checks specified by
- * the static {@code resolve} method fail
+ * If resolution fails any of the consistency checks specified by
+ * the static {@code resolve} method
* @throws IllegalArgumentException
* If the list of parents is empty, or the list has two or more
* parents with modules for different target operating systems,
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Fri Jun 16 09:20:39 2017 -0700
@@ -48,7 +48,7 @@
/**
* A finder of modules. A {@code ModuleFinder} is used to find modules during
* <a href="package-summary.html#resolution">resolution</a> or
- * <a href="package-summary.html#servicebinding">service binding</a>.
+ * <a href="Configuration.html#service-binding">service binding</a>.
*
* <p> A {@code ModuleFinder} can only find one module with a given name. A
* {@code ModuleFinder} that finds modules in a sequence of directories, for
@@ -239,30 +239,35 @@
*
* <ul>
*
- * <li><p> The module {@link ModuleDescriptor#name() name}, and {@link
- * ModuleDescriptor#version() version} if applicable, is derived from
- * the file name of the JAR file as follows: </p>
+ * <li><p> If the JAR file has the attribute "{@code Automatic-Module-Name}"
+ * in its main manifest then its value is the {@linkplain
+ * ModuleDescriptor#name() module name}. The module name is otherwise
+ * derived from the name of the JAR file. </p></li>
+ *
+ * <li><p> The {@link ModuleDescriptor#version() version}, and the
+ * module name when the attribute "{@code Automatic-Module-Name}" is not
+ * present, are derived from the file name of the JAR file as follows: </p>
*
* <ul>
*
- * <li><p> The {@code .jar} suffix is removed. </p></li>
+ * <li><p> The "{@code .jar}" suffix is removed. </p></li>
*
* <li><p> If the name matches the regular expression {@code
* "-(\\d+(\\.|$))"} then the module name will be derived from the
* subsequence preceding the hyphen of the first occurrence. The
* subsequence after the hyphen is parsed as a {@link
- * ModuleDescriptor.Version} and ignored if it cannot be parsed as
- * a {@code Version}. </p></li>
+ * ModuleDescriptor.Version Version} and ignored if it cannot be
+ * parsed as a {@code Version}. </p></li>
*
* <li><p> All non-alphanumeric characters ({@code [^A-Za-z0-9]})
* in the module name are replaced with a dot ({@code "."}), all
* repeating dots are replaced with one dot, and all leading and
* trailing dots are removed. </p></li>
*
- * <li><p> As an example, a JAR file named {@code foo-bar.jar} will
- * derive a module name {@code foo.bar} and no version. A JAR file
- * named {@code foo-bar-1.2.3-SNAPSHOT.jar} will derive a module
- * name {@code foo.bar} and {@code 1.2.3-SNAPSHOT} as the version.
+ * <li><p> As an example, a JAR file named "{@code foo-bar.jar}" will
+ * derive a module name "{@code foo.bar}" and no version. A JAR file
+ * named "{@code foo-bar-1.2.3-SNAPSHOT.jar}" will derive a module
+ * name "{@code foo.bar}" and "{@code 1.2.3-SNAPSHOT}" as the version.
* </p></li>
*
* </ul></li>
@@ -295,11 +300,12 @@
* <p> If a {@code ModuleDescriptor} cannot be created (by means of the
* {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
* automatic module then {@code FindException} is thrown. This can arise
- * when a legal module name cannot be derived from the file name of the JAR
- * file, where the JAR file contains a {@code .class} in the top-level
- * directory of the JAR file, where an entry in a service configuration
- * file is not a legal class name or its package name is not in the set of
- * packages derived for the module. </p>
+ * when the value of the "{@code Automatic-Module-Name}" attribute is not a
+ * legal module name, a legal module name cannot be derived from the file
+ * name of the JAR file, where the JAR file contains a {@code .class} in
+ * the top-level directory of the JAR file, where an entry in a service
+ * configuration file is not a legal class name or its package name is not
+ * in the set of packages derived for the module. </p>
*
* <p> In addition to JAR files, an implementation may also support modules
* that are packaged in other implementation specific module formats. If
--- a/jdk/src/java.base/share/classes/java/lang/module/package-info.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/package-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -27,118 +27,178 @@
* Classes to support module descriptors and creating configurations of modules
* by means of resolution and service binding.
*
- * <h2><a id="resolution">Resolution</a></h2>
- *
- * <p> Resolution is the process of computing the transitive closure of a set
- * of root modules over a set of observable modules by resolving the
- * dependences expressed by {@link
- * java.lang.module.ModuleDescriptor.Requires requires} clauses.
- * The <em>dependence graph</em> is augmented with edges that take account of
- * implicitly declared dependences ({@code requires transitive}) to create a
- * <em>readability graph</em>. The result of resolution is a {@link
- * java.lang.module.Configuration Configuration} that encapsulates the
- * readability graph. </p>
- *
- * <p> As an example, suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { requires m2; }
- * module m2 { requires transitive m3; }
- * module m3 { }
- * module m4 { }
- * } </pre>
- *
- * <p> If the module {@code m1} is resolved then the resulting configuration
- * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- * m1 --> m2 (meaning m1 reads m2)
- * m1 --> m3
- * m2 --> m3
- * } </pre>
- *
- * <p> Resolution is an additive process. When computing the transitive closure
- * then the dependence relation may include dependences on modules in {@link
- * java.lang.module.Configuration#parents() parent} configurations. The result
- * is a <em>relative configuration</em> that is relative to one or more parent
- * configurations and where the readability graph may have edges from modules
- * in the configuration to modules in parent configurations. </p>
- *
- * <p> As an example, suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { requires m2; requires java.xml; }
- * module m2 { }
- * } </pre>
- *
- * <p> If module {@code m1} is resolved with the configuration for the {@link
- * java.lang.ModuleLayer#boot() boot} layer as the parent then the resulting
- * configuration contains two modules ({@code m1}, {@code m2}). The edges in
- * its readability graph are:
- * <pre> {@code
- * m1 --> m2
- * m1 --> java.xml
- * } </pre>
- * where module {@code java.xml} is in the parent configuration. For
- * simplicity, this example omits the implicitly declared dependence on the
- * {@code java.base} module.
- *
- * <p> Requires clauses that are "{@code requires static}" express an optional
- * dependence (except at compile-time). If a module declares that it
- * "{@code requires static M}" then resolution does not search the observable
- * modules for "{@code M}". However, if "{@code M}" is resolved (because resolution
- * resolves a module that requires "{@code M}" without the {@link
- * java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC static} modifier)
- * then the readability graph will contain read edges for each module that
- * "{@code requires static M}". </p>
- *
- * <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
- * receive special treatment during resolution. Each automatic module is resolved
- * as if it "{@code requires transitive}" all observable automatic modules and
- * all automatic modules in the parent configurations. Each automatic module is
- * resolved so that it reads all other modules in the resulting configuration and
- * all modules in parent configurations. </p>
- *
- * <h2><a id="servicebinding">Service binding</a></h2>
- *
- * <p> Service binding is the process of augmenting a graph of resolved modules
- * from the set of observable modules induced by the service-use dependence
- * ({@code uses} and {@code provides} clauses). Any module that was not
- * previously in the graph requires resolution to compute its transitive
- * closure. Service binding is an iterative process in that adding a module
- * that satisfies some service-use dependence may introduce new service-use
- * dependences. </p>
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { exports p; uses p.S; }
- * module m2 { requires m1; provides p.S with p2.S2; }
- * module m3 { requires m1; requires m4; provides p.S with p3.S3; }
- * module m4 { }
- * } </pre>
- *
- * <p> If the module {@code m1} is resolved then the resulting graph of modules
- * has one module ({@code m1}). If the graph is augmented with modules induced
- * by the service-use dependence relation then the configuration will contain
- * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- * m2 --> m1
- * m3 --> m1
- * m3 --> m4
- * } </pre>
- * <p> The edges in the conceptual service-use graph are: </p>
- * <pre> {@code
- * m1 --> m2 (meaning m1 uses a service that is provided by m2)
- * m1 --> m3
- * } </pre>
- *
- * <h2>General Exceptions</h2>
- *
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with an array or collection containing a {@code null} element
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
*
+ *
+ * <h1><a id="resolution">Resolution</a></h1>
+ *
+ * <p> Resolution is the process of computing how modules depend on each other.
+ * The process occurs at compile time and run time. </p>
+ *
+ * <p> Resolution is a two-step process. The first step recursively enumerates
+ * the 'requires' directives of a set of root modules. If all the enumerated
+ * modules are observable, then the second step computes their readability graph.
+ * The readability graph embodies how modules depend on each other, which in
+ * turn controls access across module boundaries. </p>
+ *
+ * <h2> Step 1: Recursive enumeration </h2>
+ *
+ * <p> Recursive enumeration takes a set of module names, looks up each of their
+ * module declarations, and for each module declaration, recursively enumerates:
+ *
+ * <ul>
+ * <li> <p> the module names given by the 'requires' directives with the
+ * 'transitive' modifier, and </p></li>
+ * <li> <p> at the discretion of the host system, the module names given by
+ * the 'requires' directives without the 'transitive' modifier. </p></li>
+ * </ul>
+ *
+ * <p> Module declarations are looked up in a set of observable modules. The set
+ * of observable modules is determined in an implementation specific manner. The
+ * set of observable modules may include modules with explicit declarations
+ * (that is, with a {@code module-info.java} source file or {@code module-info.class}
+ * file) and modules with implicit declarations (that is,
+ * <a href="ModuleFinder.html#automatic-modules">automatic modules</a>).
+ * Because an automatic module has no explicit module declaration, it has no
+ * 'requires' directives of its own, although its name may be given by a
+ * 'requires' directive of an explicit module declaration. </p>
+
+ * <p> The set of root modules, whose names are the initial input to this
+ * algorithm, is determined in an implementation specific manner. The set of
+ * root modules may include automatic modules. </p>
+ *
+ * <p> If at least one automatic module is enumerated by this algorithm, then
+ * every observable automatic module must be enumerated, regardless of whether
+ * any of their names are given by 'requires' directives of explicit module
+ * declarations. </p>
+ *
+ * <p> If any of the following conditions occur, then resolution fails:
+ * <ul>
+ * <li><p> Any root module is not observable. </p></li>
+ * <li><p> Any module whose name is given by a 'requires' directive with the
+ * 'transitive' modifier is not observable. </p></li>
+ * <li><p> At the discretion of the host system, any module whose name is given
+ * by a 'requires' directive without the 'transitive' modifier is not
+ * observable. </p></li>
+ * <li><p> The algorithm in this step enumerates the same module name twice. This
+ * indicates a cycle in the 'requires' directives, disregarding any 'transitive'
+ * modifiers. </p></li>
+ * </ul>
+ *
+ * <p> Otherwise, resolution proceeds to step 2. </p>
+ *
+ * <h2> Step 2: Computing the readability graph </h2>
+ *
+ * <p> A 'requires' directive (irrespective of 'transitive') expresses that
+ * one module depends on some other module. The effect of the 'transitive'
+ * modifier is to cause additional modules to also depend on the other module.
+ * If module M 'requires transitive N', then not only does M depend on N, but
+ * any module that depends on M also depends on N. This allows M to be
+ * refactored so that some or all of its content can be moved to a new module N
+ * without breaking modules that have a 'requires M' directive. </p>
+ *
+ * <p> Module dependencies are represented by the readability graph. The
+ * readability graph is a directed graph whose vertices are the modules
+ * enumerated in step 1 and whose edges represent readability between pairs of
+ * modules. The edges are specified as follows:
+ *
+ * <p> First, readability is determined by the 'requires' directives of the
+ * enumerated modules, disregarding any 'transitive' modifiers:
+ *
+ * <ul>
+ * <li><p> For each enumerated module A that 'requires' B: A "reads" B. </p></li>
+ * <li><p> For each enumerated module X that is automatic: X "reads" every
+ * other enumerated module (it is "as if" an automatic module has 'requires'
+ * directives for every other enumerated module). </p></li>
+ * </ul>
+ *
+ * <p> Second, readability is augmented to account for 'transitive' modifiers:
+ * <ul>
+ * <li> <p> For each enumerated module A that "reads" B: </p>
+ * <ul>
+ * <li><p> If B 'requires transitive' C, then A "reads" C as well as B. This
+ * augmentation is recursive: since A "reads" C, if C 'requires transitive'
+ * D, then A "reads" D as well as C and B. </p></li>
+ * <li><p> If B is an automatic module, then A "reads" every other enumerated
+ * automatic module. (It is "as if" an automatic module has 'requires transitive'
+ * directives for every other enumerated automatic module).</p> </li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * <p> Finally, every module "reads" itself. </p>
+ *
+ * <p> If any of the following conditions occur in the readability graph, then
+ * resolution fails:
+ * <ul>
+ * <li><p> A module "reads" two or more modules with the same name. This includes
+ * the case where a module "reads" another with the same name as itself. </p></li>
+ * <li><p> Two or more modules export a package with the same name to a module
+ * that "reads" both. This includes the case where a module M containing package
+ * p "reads" another module that exports p to M. </p></li>
+ * <li><p> A module M declares that it 'uses p.S' or 'provides p.S with ...' but
+ * package p is neither in module M nor exported to M by any module that M
+ * "reads". </p></li>
+ * </ul>
+ * <p> Otherwise, resolution succeeds, and the result of resolution is the
+ * readability graph.
+ *
+ * <h2> Root modules </h2>
+ *
+ * <p> The set of root modules at compile-time is usually the set of modules
+ * being compiled. At run-time, the set of root modules is usually the
+ * application module specified to the 'java' launcher. When compiling code in
+ * the unnamed module, or at run-time when the main application class is loaded
+ * from the class path, then the default set of root modules is implementation
+ * specific (In the JDK implementation it is the module "java.se", if observable,
+ * and every observable module that exports an API). </p>
+ *
+ * <h2> Observable modules </h2>
+ *
+ * <p> The set of observable modules at both compile-time and run-time is determined
+ * by searching an abstract module path. The module path is typically composed
+ * of search paths that are searched in order: </p>
+ *
+ * <ul>
+ * <li><p> At compile-time only, a compilation module path that contains module
+ * definitions in source form. </p></li>
+ * <li><p> The upgrade module path containing compiled definitions of modules
+ * intended to be used in place of upgradeable modules built-in to the
+ * environment. </p></li>
+ * <li><p> The system modules which are the compiled modules built-in to the
+ * environment. </p></li>
+ * <li><p> The application module path which contains compiled definitions of
+ * library and application modules. </p></li>
+ * </ul>
+ *
+ * <h2> 'requires' directives with 'static' modifier </h2>
+ *
+ * <p> 'requires' directives that have the 'static' modifier express an optional
+ * dependence at run time. If a module declares that it 'requires static M' then
+ * resolution does not search the observable modules for M to satisfy the dependency.
+ * However, if M is recursively enumerated at step 1 then all modules that are
+ * enumerated and `requires static M` will read M. </p>
+ *
+ * <h2> Completeness </h2>
+ *
+ * <p> Resolution may be partial at compile-time in that the complete transitive
+ * closure may not be required to compile a set of modules. Minimally, the
+ * readability graph that is constructed and validated at compile-time includes
+ * the modules being compiled, their direct dependences, and all implicitly
+ * declared dependences (requires transitive). </p>
+ *
+ * <p> At run-time, resolution is an additive process. The recursive enumeration
+ * at step 1 may be relative to previous resolutions so that a root module,
+ * or a module named in a 'requires' directive, is not enumerated when it was
+ * enumerated by a previous (or parent) resolution. The readability graph that
+ * is the result of resolution may therefore have a vertex for a module enumerated
+ * in step 1 but with an edge to represent that the module reads a module that
+ * was enumerated by previous (or parent) resolution. </p>
+ *
* @since 9
* @spec JPMS
*/
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Fri Jun 16 09:20:39 2017 -0700
@@ -304,7 +304,7 @@
if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
// member is public
if (Modifier.isPublic(modifiers)) {
- logIfExportedByBackdoor(caller, declaringClass);
+ logIfExportedForIllegalAccess(caller, declaringClass);
return true;
}
@@ -312,14 +312,14 @@
if (Modifier.isProtected(modifiers)
&& Modifier.isStatic(modifiers)
&& isSubclassOf(caller, declaringClass)) {
- logIfExportedByBackdoor(caller, declaringClass);
+ logIfExportedForIllegalAccess(caller, declaringClass);
return true;
}
}
// package is open to caller
if (declaringModule.isOpen(pn, callerModule)) {
- logIfOpenedByBackdoor(caller, declaringClass);
+ logIfOpenedForIllegalAccess(caller, declaringClass);
return true;
}
@@ -353,26 +353,26 @@
return false;
}
- private void logIfOpenedByBackdoor(Class<?> caller, Class<?> declaringClass) {
+ private void logIfOpenedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
- logger.logIfOpenedByBackdoor(caller, declaringClass, this::toShortString);
+ logger.logIfOpenedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
- private void logIfExportedByBackdoor(Class<?> caller, Class<?> declaringClass) {
+ private void logIfExportedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
- logger.logIfExportedByBackdoor(caller, declaringClass, this::toShortString);
+ logger.logIfExportedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
@@ -634,7 +634,7 @@
}
// access okay
- logIfExportedByBackdoor(caller, memberClass);
+ logIfExportedForIllegalAccess(caller, memberClass);
// Success: Update the cache.
Object cache = (targetClass != null
--- a/jdk/src/java.base/share/classes/java/util/ServiceConfigurationError.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ServiceConfigurationError.java Fri Jun 16 09:20:39 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, 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
@@ -27,33 +27,12 @@
/**
- * Error thrown when something goes wrong while loading a service provider.
- *
- * <p> This error will be thrown in the following situations:
- *
- * <ul>
- *
- * <li> The format of a provider-configuration file violates the <a
- * href="ServiceLoader.html#format">specification</a>; </li>
- *
- * <li> An {@link java.io.IOException IOException} occurs while reading a
- * provider-configuration file; </li>
- *
- * <li> A concrete provider class named in a provider-configuration file
- * cannot be found; </li>
- *
- * <li> A concrete provider class is not a subclass of the service class;
- * </li>
- *
- * <li> A concrete provider class cannot be instantiated; or
- *
- * <li> Some other kind of error occurs. </li>
- *
- * </ul>
- *
+ * Error thrown when something goes wrong while locating, loading, or
+ * instantiating a service provider.
*
* @author Mark Reinhold
* @since 1.6
+ * @see ServiceLoader
*/
public class ServiceConfigurationError
--- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -81,16 +81,82 @@
* single class or interface could possibly unify them, so no such type is
* defined here.
*
- * <p> Providers deployed as explicit modules on the module path are
- * instantiated by a <em>provider factory</em> or directly via the provider's
- * constructor. In the module declaration then the class name specified in the
- * <i>provides</i> clause is a provider factory if it is public and defines a
- * public static no-args method named "{@code provider}". The return type of
- * the method must be assignable to the <i>service</i> type. If the class is
- * not a provider factory then it is public with a public zero-argument
- * constructor. The requirement that the provider factory or provider class
- * be public helps to document the intent that the provider will be
- * instantiated by the service-provider loading facility.
+ * <p> A service loader is created by invoking one of the static {@code load}
+ * methods that {@code ServiceLoader} defines. The resulting service loader
+ * can be used to locate and instantiate service provider implementations by
+ * means of its {@link #iterator() iterator} ({@code ServiceLoader} implements
+ * {@code Iterable}) or by consuming elements from its {@link #stream() stream}.
+ *
+ * <p> As an example, suppose the service type is {@code com.example.CodecSet}
+ * and it defines two abstract methods to obtain encoders and decoders:
+ * <pre>{@code
+ * package com.example;
+ * public interface CodecSet {
+ * Encoder getEncoder(String encodingName);
+ * Decoder getDecoder(String encodingName);
+ * }
+ * }</pre>
+ * With this example, the following uses the service loader's iterator to find
+ * a provider that supports a specific encoding:
+ * <pre>{@code
+ * public Encoder getEncoder(String encodingName) {
+ * ServiceLoader<CodeSet> loader = ServiceLoader.load(CodeSet.class);
+ * for (CodecSet cs : loader) {
+ * Encoder encoder = cs.getEncoder(encodingName);
+ * if (encoder != null)
+ * return encoder;
+ * }
+ * return null;
+ * }
+ * }</pre>
+ *
+ * <p> Selecting a provider or filtering providers will usually involve invoking
+ * a provider method. In the {@code CodeSet} example, the {@code getEncoder}
+ * method is used to select the implementation. Where selection or filtering based
+ * on the provider class is needed then it can be done when consuming the elements
+ * of the service loader's stream. As an example, the following collects the
+ * {@code CodeSet} implementations that have a specific annotation:
+ * <pre>{@code
+ * Set<CodecSet> providers = ServiceLoader.load(CodecSet.class)
+ * .stream()
+ * .filter(p -> p.type().isAnnotationPresent(Managed.class))
+ * .map(Provider::get)
+ * .collect(Collectors.toSet());
+ * }</pre>
+ *
+ * <p> Providers are located and instantiated lazily, that is, on demand. A
+ * service loader maintains a cache of the providers that have been loaded so
+ * far. Each invocation of the {@code iterator} method returns an iterator that
+ * first yields all of the elements cached from previous iteration, in
+ * instantiation order, and then lazily locates and instantiates any remaining
+ * providers, adding each one to the cache in turn. Similarly, each invocation
+ * of the {@code stream} method returns a stream that first processes all
+ * providers loaded by previous stream operations, in load order, and then lazily
+ * locates any remaining providers. Caches are cleared via the {@link #reload
+ * reload} method.
+ *
+ * <h3> Deploying provider classes in modules </h3>
+ *
+ * <p> A provider deployed as an explicit module must have an appropriate
+ * <i>provides</i> clause in its module descriptor to declare that the module
+ * provides an implementation of the service.
+ *
+ * <p> A provider deployed as an explicit module is instantiated by a
+ * <em>provider factory</em> or directly via the provider's constructor. In the
+ * module declaration then the class name specified in the <i>provides</i> clause
+ * is a provider factory if it is public and explicitly declares a public static
+ * no-args method named "{@code provider}". The return type of the method must be
+ * assignable to the <i>service</i> type. If the class is not a provider factory
+ * then it is public with a public zero-argument constructor. The requirement
+ * that the provider factory or provider class be public helps to document the
+ * intent that the provider will be instantiated by the service-provider loading
+ * facility.
+ *
+ * <p> Providers deployed as {@link
+ * java.lang.module.ModuleDescriptor#isAutomatic automatic-modules} on the
+ * module path must have a public zero-argument constructor. If the provider
+ * also declares a public static method named "{@code provider}" then it is
+ * ignored.
*
* <p> As an example, suppose a module declares the following:
*
@@ -99,38 +165,33 @@
* provides com.example.CodecSet with com.example.impl.ExtendedCodecsFactory;
* }</pre>
*
- * <p> where {@code com.example.CodecSet} is the service type, {@code
- * com.example.impl.StandardCodecs} is a provider class that is public with a
- * public no-args constructor, {@code com.example.impl.ExtendedCodecsFactory}
- * is a public class that defines a public static no-args method named
- * "{@code provider}" with a return type that is {@code CodecSet} or a subtype
- * of. For this example then {@code StandardCodecs}'s no-arg constructor will
+ * where
+ * <ul>
+ * <li> {@code com.example.CodecSet} is the service type as above </li>
+ * <li> {@code com.example.impl.StandardCodecs} is a provider class
+ * (implements {@code CodecSet}) that is public with a public no-args
+ * constructor </li>
+ * <li> {@code com.example.impl.ExtendedCodecsFactory} is a public class
+ * that explicitly declares a public static no-args method named
+ * "{@code provider}" with a return type that is {@code CodecSet} or a
+ * subtype of. </li>
+ * </ul>
+ *
+ * <p> For this example then {@code StandardCodecs}'s no-arg constructor will
* be used to instantiate {@code StandardCodecs}. {@code ExtendedCodecsFactory}
* will be treated as a provider factory and {@code
* ExtendedCodecsFactory.provider()} will be invoked to obtain the provider.
*
- * <p> Providers deployed on the class path or as {@link
- * java.lang.module.ModuleDescriptor#isAutomatic automatic-modules} on the
- * module path must have a public zero-argument constructor.
+ * <h3> Deploying provider classes on the class path </h3>
*
- * <p> An application or library using this loading facility and developed
- * and deployed as an explicit module must have an appropriate <i>uses</i>
- * clause in its <i>module descriptor</i> to declare that the module uses
- * implementations of the service. A corresponding requirement is that a
- * provider deployed as an explicit module must have an appropriate
- * <i>provides</i> clause in its module descriptor to declare that the module
- * provides an implementation of the service. The <i>uses</i> and
- * <i>provides</i> allow consumers of a service to be <i>linked</i> to modules
- * containing providers of the service.
- *
- * <p> A service provider that is packaged as a JAR file for the class path is
- * identified by placing a <i>provider-configuration file</i> in the resource
- * directory {@code META-INF/services}. The file's name is the fully-qualified
- * <a href="../lang/ClassLoader.html#name">binary name</a> of the service's
- * type. The file contains a list of fully-qualified binary names of concrete
- * provider classes, one per line. Space and tab characters surrounding each
- * name, as well as blank lines, are ignored. The comment character is
- * {@code '#'} (<code>'\u0023'</code>,
+ * <p><a id="format">A service provider that is packaged as a JAR file for
+ * the class path is identified by placing a <i>provider-configuration file</i>
+ * in the resource directory {@code META-INF/services}.</a> The file's name is
+ * the fully-qualified <a href="../lang/ClassLoader.html#name">binary name</a>
+ * of the service's type. The file contains a list of fully-qualified binary
+ * names of concrete provider classes, one per line. Space and tab characters
+ * surrounding each name, as well as blank lines, are ignored. The comment
+ * character is {@code '#'} (<code>'\u0023'</code>,
* <span style="font-size:smaller;">NUMBER SIGN</span>); on
* each line all characters following the first comment character are ignored.
* The file must be encoded in UTF-8.
@@ -141,103 +202,88 @@
* unit as the provider itself. The provider must be visible from the same
* class loader that was initially queried to locate the configuration file;
* note that this is not necessarily the class loader from which the file was
- * actually loaded.
+ * actually located.
*
- * <p> Providers are located and instantiated lazily, that is, on demand. A
- * service loader maintains a cache of the providers that have been loaded so
- * far. Each invocation of the {@link #iterator iterator} method returns an
- * iterator that first yields all of the elements cached from previous
- * iteration, in instantiation order, and then lazily locates and instantiates
- * any remaining providers, adding each one to the cache in turn. Similarly,
- * each invocation of the {@link #stream stream} method returns a stream that
- * first processes all providers loaded by previous stream operations, in load
- * order, and then lazily locates any remaining providers. Caches are cleared
- * via the {@link #reload reload} method.
- *
- * <h2> Locating providers </h2>
+ * <p> For the example, then suppose {@code com.example.impl.StandardCodecs} is
+ * packaged in a JAR file for the class path then the JAR file will contain a
+ * file named:
+ * <blockquote>{@code
+ * META-INF/services/com.example.CodecSet
+ * }</blockquote>
+ * that contains the line:
+ * <blockquote>{@code
+ * com.example.impl.StandardCodecs # Standard codecs
+ * }</blockquote>
*
- * <p> The {@code load} methods locate providers using a class loader or module
- * {@link ModuleLayer layer}. When locating providers using a class loader then
- * providers in both named and unnamed modules may be located. When locating
- * providers using a module layer then only providers in named modules in
- * the layer (or parent layers) are located.
+ * <h3> Using ServiceLoader from code in modules </h3>
*
- * <p> When locating providers using a class loader then any providers in named
- * modules defined to the class loader, or any class loader that is reachable
- * via parent delegation, are located. Additionally, providers in module layers
- * other than the {@link ModuleLayer#boot() boot} layer, where the module layer
- * contains modules defined to the class loader, or any class loader reachable
- * via parent delegation, are also located. For example, suppose there is a
- * module layer where each module is defined to its own class loader (see {@link
- * ModuleLayer#defineModulesWithManyLoaders defineModulesWithManyLoaders}). If the
- * {@code load} method is invoked to locate providers using any of these class
- * loaders for this layer then it will locate all of the providers in that
- * layer, irrespective of their defining class loader.
+ * <p> An application or library using this loading facility and developed
+ * and deployed as an explicit module must have an appropriate <i>uses</i>
+ * clause in its <i>module descriptor</i> to declare that the module uses
+ * implementations of the service. Combined with the requirement is that a
+ * provider deployed as an explicit module must have an appropriate
+ * <i>provides</i> clause allows consumers of a service to be <i>linked</i>
+ * to modules containing providers of the service.
+ *
+ * <p> For the example, if code in a module uses a service loader to load
+ * implementations of {@code com.example.CodecSet} then its module will declare
+ * the usage with: <pre>{@code uses com.example.CodecSet; }</pre>
+ *
+ * <h3> Errors </h3>
*
- * <p> In the case of unnamed modules then the service configuration files are
- * located using the class loader's {@link ClassLoader#getResources(String)
- * ClassLoader.getResources(String)} method. Any providers listed should be
- * visible via the class loader specified to the {@code load} method. If a
- * provider in a named module is listed then it is ignored - this is to avoid
- * duplicates that would otherwise arise when a module has both a
- * <i>provides</i> clause and a service configuration file in {@code
- * META-INF/services} that lists the same provider.
+ * <p> When using the service loader's {@code iterator} then its {@link
+ * Iterator#hasNext() hasNext} and {@link Iterator#next() next} methods will
+ * fail with {@link ServiceConfigurationError} if an error occurs locating or
+ * instantiating a provider. When processing the service loader's stream then
+ * {@code ServiceConfigurationError} is thrown by whatever method causes a
+ * provider class to be loaded.
*
- * <h2> Ordering </h2>
+ * <p> When loading or instantiating a provider class in a named module then
+ * {@code ServiceConfigurationError} can be thrown for the following reasons: </p>
*
- * <p> Service loaders created to locate providers using a {@code ClassLoader}
- * locate providers as follows:
* <ul>
- * <li> Providers in named modules are located before providers on the
- * class path (or more generally, unnamed modules). </li>
+ *
+ * <li> The provider class cannot be loaded. </li>
*
- * <li> When locating providers in named modules then the service loader
- * will locate providers in modules defined to the class loader, then its
- * parent class loader, its parent parent, and so on to the bootstrap class
- * loader. If a {@code ClassLoader}, or any class loader in the parent
- * delegation chain, defines modules in a custom module {@link ModuleLayer} then
- * all providers in that layer are located, irrespective of their class
- * loader. The ordering of modules defined to the same class loader, or the
- * ordering of modules in a layer, is not defined. </li>
+ * <li> The provider class is not a provider factory or is not a subclass of
+ * the service type with a public zero-argument constructor. </li>
+ *
+ * <li> The provider class explicitly declares a public static no-args method
+ * named "{@code provider}" with a return type that is not a subclass of the
+ * service type. </li>
*
- * <li> If a named module declares more than one provider then the providers
- * are located in the iteration order of the {@link
- * java.lang.module.ModuleDescriptor.Provides#providers() providers} list.
- * Providers added dynamically by instrumentation agents ({@link
- * java.lang.instrument.Instrumentation#redefineModule redefineModule})
- * are always located after providers declared by the module. </li>
+ * <li> The provider class explicitly declares more than one public static
+ * no-args method named "{@code provider}". </li>
*
- * <li> When locating providers in unnamed modules then the ordering is
- * based on the order that the class loader's {@link
- * ClassLoader#getResources(String) ClassLoader.getResources(String)}
- * method finds the service configuration files. </li>
+ * <li> The provider class is a provider factory and its public static no-args
+ * method "{@code provider}" method returns {@code null} or throws an
+ * exception. </li>
+ *
+ * <li> The provider class is not a provider factory and cannot be instantiated
+ * with its public zero-argument constructor. </li>
+ *
* </ul>
*
- * <p> Service loaders created to locate providers in a {@linkplain ModuleLayer
- * module layer} will first locate providers in the layer, before locating
- * providers in parent layers. Traversal of parent layers is depth-first with
- * each layer visited at most once. For example, suppose L0 is the boot layer,
- * L1 and L2 are custom layers with L0 as their parent. Now suppose that L3 is
- * created with L1 and L2 as the parents (in that order). Using a service
- * loader to locate providers with L3 as the content will locate providers
- * in the following order: L3, L1, L0, L2. The ordering of modules in a layer
- * is not defined.
+ * <p> When reading a provider-configuration file, or loading or instantiating a
+ * provider class named in a provider-configuration file, then {@code
+ * ServiceConfigurationError} can be thrown for the following reasons:
*
- * <h2> Selection and filtering </h2>
+ * <ul>
+ *
+ * <li> The format of the provider-configuration file violates the <a
+ * href="ServiceLoader.html#format">format</a> specified above; </li>
*
- * <p> Selecting a provider or filtering providers will usually involve invoking
- * a provider method. Where selection or filtering based on the provider class is
- * needed then it can be done using a {@link #stream() stream}. For example, the
- * following collects the providers that have a specific annotation:
- * <pre>{@code
- * Set<CodecSet> providers = ServiceLoader.load(CodecSet.class)
- * .stream()
- * .filter(p -> p.type().isAnnotationPresent(Managed.class))
- * .map(Provider::get)
- * .collect(Collectors.toSet());
- * }</pre>
+ * <li> An {@link IOException IOException} occurs while reading the
+ * provider-configuration file; </li>
+ *
+ * <li> The provider class cannot be loaded; </li>
*
- * <h2> Security </h2>
+ * <li> The provider class is not a subclass of the service type, does not
+ * define a public zero-argument constructor, or cannot be instantiated; </li>
+ *
+ * </ul>
+ *
+ * <h3> Security </h3>
*
* <p> Service loaders always execute in the security context of the caller
* of the iterator or stream methods and may also be restricted by the security
@@ -246,91 +292,16 @@
* the methods of the iterators which they return, from within a privileged
* security context.
*
- * <h2> Concurrency </h2>
+ * <h3> Concurrency </h3>
*
* <p> Instances of this class are not safe for use by multiple concurrent
* threads.
*
- * <h2> Null handling </h2>
+ * <h3> Null handling </h3>
*
* <p> Unless otherwise specified, passing a {@code null} argument to any
* method in this class will cause a {@link NullPointerException} to be thrown.
*
- * <h2> Example </h2>
- * <p> Suppose we have a service type {@code com.example.CodecSet} which is
- * intended to represent sets of encoder/decoder pairs for some protocol. In
- * this case it is an abstract class with two abstract methods:
- *
- * <blockquote><pre>
- * public abstract Encoder getEncoder(String encodingName);
- * public abstract Decoder getDecoder(String encodingName);</pre></blockquote>
- *
- * Each method returns an appropriate object or {@code null} if the provider
- * does not support the given encoding. Typical providers support more than
- * one encoding.
- *
- * <p> The {@code CodecSet} class creates and saves a single service instance
- * at initialization:
- *
- * <pre>{@code
- * private static ServiceLoader<CodecSet> codecSetLoader
- * = ServiceLoader.load(CodecSet.class);
- * }</pre>
- *
- * <p> To locate an encoder for a given encoding name it defines a static
- * factory method which iterates through the known and available providers,
- * returning only when it has located a suitable encoder or has run out of
- * providers.
- *
- * <pre>{@code
- * public static Encoder getEncoder(String encodingName) {
- * for (CodecSet cp : codecSetLoader) {
- * Encoder enc = cp.getEncoder(encodingName);
- * if (enc != null)
- * return enc;
- * }
- * return null;
- * }}</pre>
- *
- * <p> A {@code getDecoder} method is defined similarly.
- *
- * <p> If the code creating and using the service loader is developed as
- * a module then its module descriptor will declare the usage with:
- * <pre>{@code uses com.example.CodecSet;}</pre>
- *
- * <p> Now suppose that {@code com.example.impl.StandardCodecs} is an
- * implementation of the {@code CodecSet} service and developed as a module.
- * In that case then the module with the service provider module will declare
- * this in its module descriptor:
- * <pre>{@code provides com.example.CodecSet with com.example.impl.StandardCodecs;
- * }</pre>
- *
- * <p> On the other hand, suppose {@code com.example.impl.StandardCodecs} is
- * packaged in a JAR file for the class path then the JAR file will contain a
- * file named:
- * <pre>{@code META-INF/services/com.example.CodecSet}</pre>
- * that contains the single line:
- * <pre>{@code com.example.impl.StandardCodecs # Standard codecs}</pre>
- *
- * <p><span style="font-weight: bold; padding-right: 1em">Usage Note</span> If
- * the class path of a class loader that is used for provider loading includes
- * remote network URLs then those URLs will be dereferenced in the process of
- * searching for provider-configuration files.
- *
- * <p> This activity is normal, although it may cause puzzling entries to be
- * created in web-server logs. If a web server is not configured correctly,
- * however, then this activity may cause the provider-loading algorithm to fail
- * spuriously.
- *
- * <p> A web server should return an HTTP 404 (Not Found) response when a
- * requested resource does not exist. Sometimes, however, web servers are
- * erroneously configured to return an HTTP 200 (OK) response along with a
- * helpful HTML error page in such cases. This will cause a {@link
- * ServiceConfigurationError} to be thrown when this class attempts to parse
- * the HTML page as a provider-configuration file. The best solution to this
- * problem is to fix the misconfigured web server to return the correct
- * response code (HTTP 404) along with the HTML error page.
- *
* @param <S>
* The type of the service to be loaded by this loader
*
@@ -548,32 +519,83 @@
}
/**
- * Uses Class.forName to load a provider class in a module.
+ * Returns {@code true} if the provider is in an explicit module
+ */
+ private boolean inExplicitModule(Class<?> clazz) {
+ Module module = clazz.getModule();
+ return module.isNamed() && !module.getDescriptor().isAutomatic();
+ }
+
+ /**
+ * Returns the public static "provider" method if found.
*
- * @throws ServiceConfigurationError
- * If the class cannot be loaded
+ * @throws ServiceConfigurationError if there is an error finding the
+ * provider method or there is more than one public static
+ * provider method
*/
- private Class<?> loadProviderInModule(Module module, String cn) {
- Class<?> clazz = null;
- if (acc == null) {
- try {
- clazz = Class.forName(module, cn);
- } catch (LinkageError e) {
- fail(service, "Unable to load " + cn, e);
- }
- } else {
- PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
- try {
- clazz = AccessController.doPrivileged(pa);
- } catch (PrivilegedActionException pae) {
- Throwable x = pae.getCause();
- fail(service, "Unable to load " + cn, x);
- return null;
+ private Method findStaticProviderMethod(Class<?> clazz) {
+ List<Method> methods = null;
+ try {
+ methods = LANG_ACCESS.getDeclaredPublicMethods(clazz, "provider");
+ } catch (Throwable x) {
+ fail(service, "Unable to get public provider() method", x);
+ }
+ if (methods.isEmpty()) {
+ // does not declare a public provider method
+ return null;
+ }
+
+ // locate the static methods, can be at most one
+ Method result = null;
+ for (Method method : methods) {
+ int mods = method.getModifiers();
+ assert Modifier.isPublic(mods);
+ if (Modifier.isStatic(mods)) {
+ if (result != null) {
+ fail(service, clazz + " declares more than one"
+ + " public static provider() method");
+ }
+ result = method;
}
}
- if (clazz == null)
- fail(service, "Provider " + cn + " not found");
- return clazz;
+ if (result != null) {
+ Method m = result;
+ PrivilegedAction<Void> pa = () -> {
+ m.setAccessible(true);
+ return null;
+ };
+ AccessController.doPrivileged(pa);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the public no-arg constructor of a class.
+ *
+ * @throws ServiceConfigurationError if the class does not have
+ * public no-arg constructor
+ */
+ private Constructor<?> getConstructor(Class<?> clazz) {
+ PrivilegedExceptionAction<Constructor<?>> pa
+ = new PrivilegedExceptionAction<>() {
+ @Override
+ public Constructor<?> run() throws Exception {
+ Constructor<?> ctor = clazz.getConstructor();
+ if (inExplicitModule(clazz))
+ ctor.setAccessible(true);
+ return ctor;
+ }
+ };
+ Constructor<?> ctor = null;
+ try {
+ ctor = AccessController.doPrivileged(pa);
+ } catch (Throwable x) {
+ if (x instanceof PrivilegedActionException)
+ x = x.getCause();
+ String cn = clazz.getName();
+ fail(service, cn + " Unable to get public no-arg constructor", x);
+ }
+ return ctor;
}
/**
@@ -581,65 +603,33 @@
* permissions, the static factory to obtain the provider or the
* provider's no-arg constructor.
*/
- private final static class ProviderImpl<S> implements Provider<S> {
+ private static class ProviderImpl<S> implements Provider<S> {
final Class<S> service;
+ final Class<? extends S> type;
+ final Method factoryMethod; // factory method or null
+ final Constructor<? extends S> ctor; // public no-args constructor or null
final AccessControlContext acc;
- final Method factoryMethod; // factory method or null
- final Class<? extends S> type;
- final Constructor<? extends S> ctor; // public no-args constructor or null
-
- /**
- * Creates a Provider.
- *
- * @param service
- * The service type
- * @param clazz
- * The provider (or provider factory) class
- * @param acc
- * The access control context when running with security manager
- *
- * @throws ServiceConfigurationError
- * If the class is not public; If the class defines a public
- * static provider() method with a return type that is assignable
- * to the service type or the class is not a provider class with
- * a public no-args constructor.
- */
- @SuppressWarnings("unchecked")
- ProviderImpl(Class<?> service, Class<?> clazz, AccessControlContext acc) {
- this.service = (Class<S>) service;
+ ProviderImpl(Class<S> service,
+ Class<? extends S> type,
+ Method factoryMethod,
+ AccessControlContext acc) {
+ this.service = service;
+ this.type = type;
+ this.factoryMethod = factoryMethod;
+ this.ctor = null;
this.acc = acc;
+ }
- int mods = clazz.getModifiers();
- if (!Modifier.isPublic(mods)) {
- fail(service, clazz + " is not public");
- }
-
- // if the class is in an explicit module then see if it is
- // a provider factory class
- Method factoryMethod = null;
- if (inExplicitModule(clazz)) {
- factoryMethod = findStaticProviderMethod(clazz);
- if (factoryMethod != null) {
- Class<?> returnType = factoryMethod.getReturnType();
- if (!service.isAssignableFrom(returnType)) {
- fail(service, factoryMethod + " return type not a subtype");
- }
- }
- }
- this.factoryMethod = factoryMethod;
-
- if (factoryMethod == null) {
- // no factory method so must have a public no-args constructor
- if (!service.isAssignableFrom(clazz)) {
- fail(service, clazz.getName() + " not a subtype");
- }
- this.type = (Class<? extends S>) clazz;
- this.ctor = (Constructor<? extends S>) getConstructor(clazz);
- } else {
- this.type = (Class<? extends S>) factoryMethod.getReturnType();
- this.ctor = null;
- }
+ ProviderImpl(Class<S> service,
+ Class<? extends S> type,
+ Constructor<? extends S> ctor,
+ AccessControlContext acc) {
+ this.service = service;
+ this.type = type;
+ this.factoryMethod = null;
+ this.ctor = ctor;
+ this.acc = acc;
}
@Override
@@ -657,72 +647,6 @@
}
/**
- * Returns {@code true} if the provider is in an explicit module
- */
- private boolean inExplicitModule(Class<?> clazz) {
- Module module = clazz.getModule();
- return module.isNamed() && !module.getDescriptor().isAutomatic();
- }
-
- /**
- * Returns the public static provider method if found.
- *
- * @throws ServiceConfigurationError if there is an error finding the
- * provider method
- */
- private Method findStaticProviderMethod(Class<?> clazz) {
- Method method = null;
- try {
- method = LANG_ACCESS.getMethodOrNull(clazz, "provider");
- } catch (Throwable x) {
- fail(service, "Unable to get public provider() method", x);
- }
- if (method != null) {
- int mods = method.getModifiers();
- if (Modifier.isStatic(mods)) {
- assert Modifier.isPublic(mods);
- Method m = method;
- PrivilegedAction<Void> pa = () -> {
- m.setAccessible(true);
- return null;
- };
- AccessController.doPrivileged(pa);
- return method;
- }
- }
- return null;
- }
-
- /**
- * Returns the public no-arg constructor of a class.
- *
- * @throws ServiceConfigurationError if the class does not have
- * public no-arg constructor
- */
- private Constructor<?> getConstructor(Class<?> clazz) {
- PrivilegedExceptionAction<Constructor<?>> pa
- = new PrivilegedExceptionAction<>() {
- @Override
- public Constructor<?> run() throws Exception {
- Constructor<?> ctor = clazz.getConstructor();
- if (inExplicitModule(clazz))
- ctor.setAccessible(true);
- return ctor;
- }
- };
- Constructor<?> ctor = null;
- try {
- ctor = AccessController.doPrivileged(pa);
- } catch (Throwable x) {
- if (x instanceof PrivilegedActionException)
- x = x.getCause();
- String cn = clazz.getName();
- fail(service, cn + " Unable to get public no-arg constructor", x);
- }
- return ctor;
- }
-
- /**
* Invokes the provider's "provider" method to instantiate a provider.
* When running with a security manager then the method runs with
* permissions that are restricted by the security context of whatever
@@ -808,7 +732,7 @@
@Override
public int hashCode() {
- return Objects.hash(type, acc);
+ return Objects.hash(service, type, acc);
}
@Override
@@ -817,12 +741,84 @@
return false;
@SuppressWarnings("unchecked")
ProviderImpl<?> that = (ProviderImpl<?>)ob;
- return this.type == that.type
+ return this.service == that.service
+ && this.type == that.type
&& Objects.equals(this.acc, that.acc);
}
}
/**
+ * Loads a service provider in a module.
+ *
+ * Returns {@code null} if the service provider's module doesn't read
+ * the module with the service type.
+ *
+ * @throws ServiceConfigurationError if the class cannot be loaded or
+ * isn't the expected sub-type (or doesn't define a provider
+ * factory method that returns the expected type)
+ */
+ private Provider<S> loadProvider(ServiceProvider provider) {
+ Module module = provider.module();
+ if (!module.canRead(service.getModule())) {
+ // module does not read the module with the service type
+ return null;
+ }
+
+ String cn = provider.providerName();
+ Class<?> clazz = null;
+ if (acc == null) {
+ try {
+ clazz = Class.forName(module, cn);
+ } catch (LinkageError e) {
+ fail(service, "Unable to load " + cn, e);
+ }
+ } else {
+ PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
+ try {
+ clazz = AccessController.doPrivileged(pa);
+ } catch (PrivilegedActionException pae) {
+ Throwable x = pae.getCause();
+ fail(service, "Unable to load " + cn, x);
+ return null;
+ }
+ }
+ if (clazz == null) {
+ fail(service, "Provider " + cn + " not found");
+ }
+
+ int mods = clazz.getModifiers();
+ if (!Modifier.isPublic(mods)) {
+ fail(service, clazz + " is not public");
+ }
+
+ // if provider in explicit module then check for static factory method
+ if (inExplicitModule(clazz)) {
+ Method factoryMethod = findStaticProviderMethod(clazz);
+ if (factoryMethod != null) {
+ Class<?> returnType = factoryMethod.getReturnType();
+ if (!service.isAssignableFrom(returnType)) {
+ fail(service, factoryMethod + " return type not a subtype");
+ }
+
+ @SuppressWarnings("unchecked")
+ Class<? extends S> type = (Class<? extends S>) returnType;
+ return new ProviderImpl<S>(service, type, factoryMethod, acc);
+ }
+ }
+
+ // no factory method so must be a subtype
+ if (!service.isAssignableFrom(clazz)) {
+ fail(service, clazz.getName() + " not a subtype");
+ }
+
+ @SuppressWarnings("unchecked")
+ Class<? extends S> type = (Class<? extends S>) clazz;
+ @SuppressWarnings("unchecked")
+ Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz);
+ return new ProviderImpl<S>(service, type, ctor, acc);
+ }
+
+ /**
* Implements lazy service provider lookup of service providers that
* are provided by modules in a module layer (or parent layers)
*/
@@ -832,7 +828,9 @@
Deque<ModuleLayer> stack = new ArrayDeque<>();
Set<ModuleLayer> visited = new HashSet<>();
Iterator<ServiceProvider> iterator;
- ServiceProvider next; // next provider to load
+
+ Provider<T> nextProvider;
+ ServiceConfigurationError nextError;
LayerLookupIterator() {
visited.add(layer);
@@ -846,33 +844,36 @@
@Override
public boolean hasNext() {
- // already have the next provider cached
- if (next != null)
- return true;
+ while (nextProvider == null && nextError == null) {
+ // get next provider to load
+ while (iterator == null || !iterator.hasNext()) {
+ // next layer (DFS order)
+ if (stack.isEmpty())
+ return false;
- while (true) {
-
- // next provider (or provider factory)
- if (iterator != null && iterator.hasNext()) {
- next = iterator.next();
- return true;
+ ModuleLayer layer = stack.pop();
+ List<ModuleLayer> parents = layer.parents();
+ for (int i = parents.size() - 1; i >= 0; i--) {
+ ModuleLayer parent = parents.get(i);
+ if (!visited.contains(parent)) {
+ visited.add(parent);
+ stack.push(parent);
+ }
+ }
+ iterator = providers(layer);
}
- // next layer (DFS order)
- if (stack.isEmpty())
- return false;
-
- ModuleLayer layer = stack.pop();
- List<ModuleLayer> parents = layer.parents();
- for (int i = parents.size() - 1; i >= 0; i--) {
- ModuleLayer parent = parents.get(i);
- if (!visited.contains(parent)) {
- visited.add(parent);
- stack.push(parent);
- }
+ // attempt to load provider
+ ServiceProvider provider = iterator.next();
+ try {
+ @SuppressWarnings("unchecked")
+ Provider<T> next = (Provider<T>) loadProvider(provider);
+ nextProvider = next;
+ } catch (ServiceConfigurationError e) {
+ nextError = e;
}
- iterator = providers(layer);
}
+ return true;
}
@Override
@@ -880,15 +881,16 @@
if (!hasNext())
throw new NoSuchElementException();
- // take next provider
- ServiceProvider provider = next;
- next = null;
-
- // attempt to load provider
- Module module = provider.module();
- String cn = provider.providerName();
- Class<?> clazz = loadProviderInModule(module, cn);
- return new ProviderImpl<T>(service, clazz, acc);
+ Provider<T> provider = nextProvider;
+ if (provider != null) {
+ nextProvider = null;
+ return provider;
+ } else {
+ ServiceConfigurationError e = nextError;
+ assert e != null;
+ nextError = null;
+ throw e;
+ }
}
}
@@ -902,7 +904,9 @@
{
ClassLoader currentLoader;
Iterator<ServiceProvider> iterator;
- ServiceProvider next; // next provider to load
+
+ Provider<T> nextProvider;
+ ServiceConfigurationError nextError;
ModuleServicesLookupIterator() {
this.currentLoader = loader;
@@ -919,13 +923,25 @@
}
/**
+ * Returns the class loader that a module is defined to
+ */
+ private ClassLoader loaderFor(Module module) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ return module.getClassLoader();
+ } else {
+ PrivilegedAction<ClassLoader> pa = module::getClassLoader;
+ return AccessController.doPrivileged(pa);
+ }
+ }
+
+ /**
* Returns an iterator to iterate over the implementations of {@code
* service} in modules defined to the given class loader or in custom
* layers with a module defined to this class loader.
*/
private Iterator<ServiceProvider> iteratorFor(ClassLoader loader) {
-
- // modules defined to this class loader
+ // modules defined to the class loader
ServicesCatalog catalog;
if (loader == null) {
catalog = BootLoader.getServicesCatalog();
@@ -939,17 +955,20 @@
providers = catalog.findServices(serviceName);
}
- // modules in custom layers that define modules to the class loader
- if (loader == null) {
+ // modules in layers that define modules to the class loader
+ ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
+ if (loader == null || loader == platformClassLoader) {
return providers.iterator();
} else {
List<ServiceProvider> allProviders = new ArrayList<>(providers);
- ModuleLayer bootLayer = ModuleLayer.boot();
Iterator<ModuleLayer> iterator = LANG_ACCESS.layers(loader).iterator();
while (iterator.hasNext()) {
ModuleLayer layer = iterator.next();
- if (layer != bootLayer) {
- allProviders.addAll(providers(layer));
+ for (ServiceProvider sp : providers(layer)) {
+ ClassLoader l = loaderFor(sp.module());
+ if (l != null && l != platformClassLoader) {
+ allProviders.add(sp);
+ }
}
}
return allProviders.iterator();
@@ -958,24 +977,28 @@
@Override
public boolean hasNext() {
- // already have the next provider cached
- if (next != null)
- return true;
-
- while (true) {
- if (iterator.hasNext()) {
- next = iterator.next();
- return true;
+ while (nextProvider == null && nextError == null) {
+ // get next provider to load
+ while (!iterator.hasNext()) {
+ if (currentLoader == null) {
+ return false;
+ } else {
+ currentLoader = currentLoader.getParent();
+ iterator = iteratorFor(currentLoader);
+ }
}
- // move to the next class loader if possible
- if (currentLoader == null) {
- return false;
- } else {
- currentLoader = currentLoader.getParent();
- iterator = iteratorFor(currentLoader);
+ // attempt to load provider
+ ServiceProvider provider = iterator.next();
+ try {
+ @SuppressWarnings("unchecked")
+ Provider<T> next = (Provider<T>) loadProvider(provider);
+ nextProvider = next;
+ } catch (ServiceConfigurationError e) {
+ nextError = e;
}
}
+ return true;
}
@Override
@@ -983,15 +1006,16 @@
if (!hasNext())
throw new NoSuchElementException();
- // take next provider
- ServiceProvider provider = next;
- next = null;
-
- // attempt to load provider
- Module module = provider.module();
- String cn = provider.providerName();
- Class<?> clazz = loadProviderInModule(module, cn);
- return new ProviderImpl<T>(service, clazz, acc);
+ Provider<T> provider = nextProvider;
+ if (provider != null) {
+ nextProvider = null;
+ return provider;
+ } else {
+ ServiceConfigurationError e = nextError;
+ assert e != null;
+ nextError = null;
+ throw e;
+ }
}
}
@@ -1008,8 +1032,9 @@
Set<String> providerNames = new HashSet<>(); // to avoid duplicates
Enumeration<URL> configs;
Iterator<String> pending;
- Class<?> nextClass;
- String nextErrorMessage; // when hasNext fails with CNFE
+
+ Provider<T> nextProvider;
+ ServiceConfigurationError nextError;
LazyClassPathLookupIterator() { }
@@ -1068,51 +1093,71 @@
return names.iterator();
}
- private boolean hasNextService() {
- if (nextClass != null || nextErrorMessage != null) {
- return true;
- }
-
- Class<?> clazz;
- do {
- if (configs == null) {
- try {
- String fullName = PREFIX + service.getName();
- if (loader == null) {
- configs = ClassLoader.getSystemResources(fullName);
- } else if (loader == ClassLoaders.platformClassLoader()) {
- // The platform classloader doesn't have a class path,
- // but the boot loader might.
- if (BootLoader.hasClassPath()) {
- configs = BootLoader.findResources(fullName);
- } else {
- configs = Collections.emptyEnumeration();
- }
+ /**
+ * Loads and returns the next provider class.
+ */
+ private Class<?> nextProviderClass() {
+ if (configs == null) {
+ try {
+ String fullName = PREFIX + service.getName();
+ if (loader == null) {
+ configs = ClassLoader.getSystemResources(fullName);
+ } else if (loader == ClassLoaders.platformClassLoader()) {
+ // The platform classloader doesn't have a class path,
+ // but the boot loader might.
+ if (BootLoader.hasClassPath()) {
+ configs = BootLoader.findResources(fullName);
} else {
- configs = loader.getResources(fullName);
+ configs = Collections.emptyEnumeration();
}
- } catch (IOException x) {
- fail(service, "Error locating configuration files", x);
+ } else {
+ configs = loader.getResources(fullName);
}
+ } catch (IOException x) {
+ fail(service, "Error locating configuration files", x);
}
- while ((pending == null) || !pending.hasNext()) {
- if (!configs.hasMoreElements()) {
- return false;
- }
- pending = parse(configs.nextElement());
+ }
+ while ((pending == null) || !pending.hasNext()) {
+ if (!configs.hasMoreElements()) {
+ return null;
}
- String cn = pending.next();
+ pending = parse(configs.nextElement());
+ }
+ String cn = pending.next();
+ try {
+ return Class.forName(cn, false, loader);
+ } catch (ClassNotFoundException x) {
+ fail(service, "Provider " + cn + " not found");
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean hasNextService() {
+ while (nextProvider == null && nextError == null) {
try {
- clazz = Class.forName(cn, false, loader);
- } catch (ClassNotFoundException x) {
- // don't throw SCE here to long standing behavior
- nextErrorMessage = "Provider " + cn + " not found";
- return true;
+ Class<?> clazz = nextProviderClass();
+ if (clazz == null)
+ return false;
+
+ if (clazz.getModule().isNamed()) {
+ // ignore class if in named module
+ continue;
+ }
+
+ if (service.isAssignableFrom(clazz)) {
+ Class<? extends S> type = (Class<? extends S>) clazz;
+ Constructor<? extends S> ctor
+ = (Constructor<? extends S>)getConstructor(clazz);
+ ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor, acc);
+ nextProvider = (ProviderImpl<T>) p;
+ } else {
+ fail(service, clazz.getName() + " not a subtype");
+ }
+ } catch (ServiceConfigurationError e) {
+ nextError = e;
}
-
- } while (clazz.getModule().isNamed()); // ignore if in named module
-
- nextClass = clazz;
+ }
return true;
}
@@ -1120,17 +1165,16 @@
if (!hasNextService())
throw new NoSuchElementException();
- // throw any SCE with error recorded by hasNext
- if (nextErrorMessage != null) {
- String msg = nextErrorMessage;
- nextErrorMessage = null;
- fail(service, msg);
+ Provider<T> provider = nextProvider;
+ if (provider != null) {
+ nextProvider = null;
+ return provider;
+ } else {
+ ServiceConfigurationError e = nextError;
+ assert e != null;
+ nextError = null;
+ throw e;
}
-
- // return next provider
- Class<?> clazz = nextClass;
- nextClass = null;
- return new ProviderImpl<T>(service, clazz, acc);
}
@Override
@@ -1420,7 +1464,86 @@
/**
* Creates a new service loader for the given service type and class
- * loader.
+ * loader. The service loader locates service providers in both named and
+ * unnamed modules:
+ *
+ * <ul>
+ * <li><p> Service providers are located in named modules defined to the
+ * class loader, or any class loader that is reachable via parent
+ * delegation. </p>
+ *
+ * <p> Additionally, and with the exception of the bootstrap and {@linkplain
+ * ClassLoader#getPlatformClassLoader() platform} class loaders, if the
+ * class loader, or any class loader reachable via parent delegation,
+ * defines modules in a module layer then the providers in the module layer
+ * are located. For example, suppose there is a module layer where each
+ * module is defined to its own class loader (see {@link
+ * ModuleLayer#defineModulesWithManyLoaders defineModulesWithManyLoaders}).
+ * If this {@code ServiceLoader.load} method is invoked to locate providers
+ * using any of the class loaders created for this layer then it will locate
+ * all of the providers in that layer, irrespective of their defining class
+ * loader. </p></li>
+ *
+ * <li><p> A provider is an unnamed modules is located if its class
+ * name is listed in a service configuration file located by the the class
+ * loader's {@link ClassLoader#getResources(String) getResources} method.
+ * The provider class must be visible to the class loader. If a provider
+ * class is in a named module is listed then it is ignored (this is to
+ * avoid duplicates that would otherwise arise when a module has both a
+ * <i>provides</i> clause and a service configuration file in {@code
+ * META-INF/services} that lists the same provider). </p> </li>
+ * </ul>
+ *
+ * <p> The ordering that the service loader's iterator and stream locate
+ * providers and yield elements is as follows:
+ *
+ * <ul>
+ * <li><p> Providers in named modules are located before service
+ * providers in unnamed modules.</p></li>
+ *
+ * <li><p> When locating providers in named modules then the service
+ * loader will first locate any service providers in modules defined to
+ * the class loader, then its parent class loader, its parent parent,
+ * and so on to the bootstrap class loader. If a class loader or any
+ * class loader in the parent delegation chain, defines modules in a
+ * module layer then all providers in that layer are located
+ * (irrespective of their class loader) before providers in the parent
+ * class loader are located. The ordering of modules defined to the
+ * same class loader, or the ordering of modules in a layer, is not
+ * defined. </p></li>
+ *
+ * <li><p> If a named module declares more than one provider then the
+ * providers are located in the order that its module descriptor
+ * {@linkplain java.lang.module.ModuleDescriptor.Provides#providers()
+ * lists the providers}. Providers added dynamically by instrumentation
+ * agents (see {@link java.lang.instrument.Instrumentation#redefineModule
+ * redefineModule}) are always located after providers declared by the
+ * module. </p></li>
+ *
+ * <li><p> When locating providers in unnamed modules then the
+ * ordering is based on the order that the class loader's {@link
+ * ClassLoader#getResources(String) getResources} method finds the
+ * service configuration files and within that, the order that the class
+ * names are listed in the file. </p></li>
+ * </ul>
+ *
+ * @apiNote If the class path of the class loader includes remote network
+ * URLs then those URLs may be dereferenced in the process of searching for
+ * provider-configuration files.
+ *
+ * <p> This activity is normal, although it may cause puzzling entries to be
+ * created in web-server logs. If a web server is not configured correctly,
+ * however, then this activity may cause the provider-loading algorithm to fail
+ * spuriously.
+ *
+ * <p> A web server should return an HTTP 404 (Not Found) response when a
+ * requested resource does not exist. Sometimes, however, web servers are
+ * erroneously configured to return an HTTP 200 (OK) response along with a
+ * helpful HTML error page in such cases. This will cause a {@link
+ * ServiceConfigurationError} to be thrown when this class attempts to parse
+ * the HTML page as a provider-configuration file. The best solution to this
+ * problem is to fix the misconfigured web server to return the correct
+ * response code (HTTP 404) along with the HTML error page.
*
* @param <S> the class of the service type
*
@@ -1457,13 +1580,13 @@
*
* <p> An invocation of this convenience method of the form
* <pre>{@code
- * ServiceLoader.load(service)
+ * ServiceLoader.load(service)
* }</pre>
*
* is equivalent to
*
* <pre>{@code
- * ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
+ * ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
* }</pre>
*
* @apiNote Service loader objects obtained with this method should not be
@@ -1502,7 +1625,7 @@
* <p> This convenience method is equivalent to: </p>
*
* <pre>{@code
- * ServiceLoader.load(service, ClassLoader.getPlatformClassLoader())
+ * ServiceLoader.load(service, ClassLoader.getPlatformClassLoader())
* }</pre>
*
* <p> This method is intended for use when only installed providers are
@@ -1532,9 +1655,30 @@
}
/**
- * Creates a new service loader for the given service type that loads
- * service providers from modules in the given {@code ModuleLayer} and its
- * ancestors.
+ * Creates a new service loader for the given service type to load service
+ * providers from modules in the given module layer and its ancestors. It
+ * does not locate providers in unnamed modules.
+ *
+ * <p> The ordering that the service loader's iterator and stream locate
+ * providers and yield elements is as follows:
+ *
+ * <ul>
+ * <li><p> Providers are located in a module layer before locating providers
+ * in parent layers. Traversal of parent layers is depth-first with each
+ * layer visited at most once. For example, suppose L0 is the boot layer, L1
+ * and L2 are modules layers with L0 as their parent. Now suppose that L3 is
+ * created with L1 and L2 as the parents (in that order). Using a service
+ * loader to locate providers with L3 as the context will locate providers
+ * in the following order: L3, L1, L0, L2. </p></li>
+ *
+ * <li><p> If a named module declares more than one provider then the
+ * providers are located in the order that its module descriptor
+ * {@linkplain java.lang.module.ModuleDescriptor.Provides#providers()
+ * lists the providers}. Providers added dynamically by instrumentation
+ * agents are always located after providers declared by the module. </p></li>
+ *
+ * <li><p> The ordering of modules in a module layer is not defined. </p></li>
+ * </ul>
*
* @apiNote Unlike the other load methods defined here, the service type
* is the second parameter. The reason for this is to avoid source
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Fri Jun 16 09:20:39 2017 -0700
@@ -49,8 +49,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.Attributes;
@@ -336,16 +338,43 @@
}
}
- // search class path
+ // class path (not checked)
Enumeration<URL> e = findResourcesOnClassPath(name);
- while (e.hasMoreElements()) {
- URL url = checkURL(e.nextElement());
- if (url != null) {
- checked.add(url);
+
+ // concat the checked URLs and the (not checked) class path
+ return new Enumeration<>() {
+ final Iterator<URL> iterator = checked.iterator();
+ URL next;
+ private boolean hasNext() {
+ if (next != null) {
+ return true;
+ } else if (iterator.hasNext()) {
+ next = iterator.next();
+ return true;
+ } else {
+ // need to check each URL
+ while (e.hasMoreElements() && next == null) {
+ next = checkURL(e.nextElement());
+ }
+ return next != null;
+ }
}
- }
+ @Override
+ public boolean hasMoreElements() {
+ return hasNext();
+ }
+ @Override
+ public URL nextElement() {
+ if (hasNext()) {
+ URL result = next;
+ next = null;
+ return result;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ };
- return Collections.enumeration(checked);
}
/**
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Fri Jun 16 09:20:39 2017 -0700
@@ -28,6 +28,7 @@
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleReader;
@@ -52,11 +53,17 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
+import java.util.Spliterator;
+import java.util.Spliterators;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.Resources;
@@ -79,8 +86,8 @@
* loader. This allows automatic modules (for example) to link to types in the
* unnamed module of the parent class loader.
*
- * @see ModuleModuleLayer#defineModulesWithOneLoader
- * @see ModuleModuleLayer#defineModulesWithManyLoaders
+ * @see ModuleLayer#defineModulesWithOneLoader
+ * @see ModuleLayer#defineModulesWithManyLoaders
*/
public final class Loader extends SecureClassLoader {
@@ -303,7 +310,6 @@
// -- resources --
-
/**
* Returns a URL to a resource of the given name in a module defined to
* this class loader.
@@ -388,33 +394,96 @@
@Override
public Enumeration<URL> findResources(String name) throws IOException {
- List<URL> urls = new ArrayList<>();
+ return Collections.enumeration(findResourcesAsList(name));
+ }
+
+ @Override
+ public URL getResource(String name) {
+ Objects.requireNonNull(name);
+
+ // this loader
+ URL url = findResource(name);
+ if (url != null) {
+ return url;
+ } else {
+ // parent loader
+ return parent.getResource(name);
+ }
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String name) throws IOException {
+ Objects.requireNonNull(name);
+
+ // this loader
+ List<URL> urls = findResourcesAsList(name);
+
+ // parent loader
+ Enumeration<URL> e = parent.getResources(name);
+
+ // concat the URLs with the URLs returned by the parent
+ return new Enumeration<>() {
+ final Iterator<URL> iterator = urls.iterator();
+ @Override
+ public boolean hasMoreElements() {
+ return (iterator.hasNext() || e.hasMoreElements());
+ }
+ @Override
+ public URL nextElement() {
+ if (iterator.hasNext()) {
+ return iterator.next();
+ } else {
+ return e.nextElement();
+ }
+ }
+ };
+ }
+
+ @Override
+ public Stream<URL> resources(String name) {
+ Objects.requireNonNull(name);
+ // ordering not specified
+ int characteristics = (Spliterator.NONNULL | Spliterator.IMMUTABLE |
+ Spliterator.SIZED | Spliterator.SUBSIZED);
+ Supplier<Spliterator<URL>> supplier = () -> {
+ try {
+ List<URL> urls = findResourcesAsList(name);
+ return Spliterators.spliterator(urls, characteristics);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ };
+ Stream<URL> s1 = StreamSupport.stream(supplier, characteristics, false);
+ Stream<URL> s2 = parent.resources(name);
+ return Stream.concat(s1, s2);
+ }
+
+ /**
+ * Finds the resources with the given name in this class loader.
+ */
+ private List<URL> findResourcesAsList(String name) throws IOException {
String pn = Resources.toPackageName(name);
LoadedModule module = localPackageToModule.get(pn);
if (module != null) {
- try {
- URL url = findResource(module.name(), name);
- if (url != null
+ URL url = findResource(module.name(), name);
+ if (url != null
&& (name.endsWith(".class")
- || url.toString().endsWith("/")
- || isOpen(module.mref(), pn))) {
- urls.add(url);
- }
- } catch (IOException ioe) {
- // ignore
+ || url.toString().endsWith("/")
+ || isOpen(module.mref(), pn))) {
+ return List.of(url);
+ } else {
+ return Collections.emptyList();
}
} else {
+ List<URL> urls = new ArrayList<>();
for (ModuleReference mref : nameToModule.values()) {
- try {
- URL url = findResource(mref.descriptor().name(), name);
- if (url != null)
- urls.add(url);
- } catch (IOException ioe) {
- // ignore
+ URL url = findResource(mref.descriptor().name(), name);
+ if (url != null) {
+ urls.add(url);
}
}
+ return urls;
}
- return Collections.enumeration(urls);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Fri Jun 16 09:20:39 2017 -0700
@@ -32,6 +32,8 @@
import java.net.URI;
import java.security.AccessControlContext;
import java.security.ProtectionDomain;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
@@ -44,13 +46,15 @@
public interface JavaLangAccess {
/**
- * Returns a {@code Method} object that reflects the specified public
- * member method of the given class. Returns {@code null} if the
- * method is not defined.
+ * Returns the list of {@code Method} objects for the declared public
+ * methods of this class or interface that have the specified method name
+ * and parameter types.
*/
- Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes);
+ List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes);
- /** Return the constant pool for a class. */
+ /**
+ * Return the constant pool for a class.
+ */
ConstantPool getConstantPool(Class<?> klass);
/**
@@ -95,7 +99,9 @@
*/
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass);
- /** Set thread's blocker field. */
+ /**
+ * Set thread's blocker field.
+ */
void blockedOn(Thread t, Interruptible b);
/**
@@ -155,11 +161,6 @@
Class<?> findBootstrapClassOrNull(ClassLoader cl, String name);
/**
- * Returns the Packages for the given class loader.
- */
- Stream<Package> packages(ClassLoader cl);
-
- /**
* Define a Package of the given name and module by the given class loader.
*/
Package definePackage(ClassLoader cl, String name, Module module);
@@ -223,16 +224,31 @@
void addOpens(Module m1, String pkg, Module m2);
/**
- * Updates a module m to open a package to all unnamed modules.
+ * Updates module m to open a package to all unnamed modules.
*/
void addOpensToAllUnnamed(Module m, String pkg);
/**
- * Updates a module m to use a service.
+ * Updates module m to open all packages returned by the given iterator.
+ */
+ void addOpensToAllUnnamed(Module m, Iterator<String> packages);
+
+ /**
+ * Updates module m to use a service.
*/
void addUses(Module m, Class<?> service);
/**
+ * Returns true if module m reflectively exports a package to other
+ */
+ boolean isReflectivelyExported(Module module, String pn, Module other);
+
+ /**
+ * Returns true if module m reflectively opens a package to other
+ */
+ boolean isReflectivelyOpened(Module module, String pn, Module other);
+
+ /**
* Returns the ServicesCatalog for the given Layer.
*/
ServicesCatalog getServicesCatalog(ModuleLayer layer);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java Fri Jun 16 09:20:39 2017 -0700
@@ -33,146 +33,240 @@
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.StringJoiner;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import static java.util.Collections.*;
-import jdk.internal.loader.BootLoader;
-import sun.security.action.GetPropertyAction;
+import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.misc.SharedSecrets;
/**
- * Supports logging of access to members of API packages that are exported or
- * opened via backdoor mechanisms to code in unnamed modules.
+ * Supports logging of access to members of exported and concealed packages
+ * that are opened to code in unnamed modules for illegal access.
*/
public final class IllegalAccessLogger {
/**
- * Holder class to lazily create the StackWalker object and determine
- * if the stack trace should be printed
+ * Logger modes
*/
- static class Holder {
- static final StackWalker STACK_WALKER;
- static final boolean PRINT_STACK_TRACE;
+ public static enum Mode {
+ /**
+ * Prints a warning when an illegal access succeeds and then
+ * discards the logger so that there is no further output.
+ */
+ ONESHOT,
+ /**
+ * Print warnings when illegal access succeeds
+ */
+ WARN,
+ /**
+ * Prints warnings and a stack trace when illegal access succeeds
+ */
+ DEBUG,
+ }
+
+ /**
+ * A builder for IllegalAccessLogger objects.
+ */
+ public static class Builder {
+ private final Mode mode;
+ private final PrintStream warningStream;
+ private final Map<Module, Set<String>> moduleToConcealedPackages;
+ private final Map<Module, Set<String>> moduleToExportedPackages;
+ private boolean complete;
+
+ private void ensureNotComplete() {
+ if (complete) throw new IllegalStateException();
+ }
- static {
- PrivilegedAction<StackWalker> pa = () ->
- StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
- STACK_WALKER = AccessController.doPrivileged(pa);
+ /**
+ * Creates a builder.
+ */
+ public Builder(Mode mode, PrintStream warningStream) {
+ this.mode = mode;
+ this.warningStream = warningStream;
+ this.moduleToConcealedPackages = new HashMap<>();
+ this.moduleToExportedPackages = new HashMap<>();
+ }
- String name = "sun.reflect.debugModuleAccessChecks";
- String value = GetPropertyAction.privilegedGetProperty(name, null);
- PRINT_STACK_TRACE = "access" .equals(value);
+ /**
+ * Adding logging of reflective-access to any member of a type in
+ * otherwise concealed packages.
+ */
+ public Builder logAccessToConcealedPackages(Module m, Set<String> packages) {
+ ensureNotComplete();
+ moduleToConcealedPackages.put(m, unmodifiableSet(packages));
+ return this;
+ }
+
+ /**
+ * Adding logging of reflective-access to non-public members/types in
+ * otherwise exported (not open) packages.
+ */
+ public Builder logAccessToExportedPackages(Module m, Set<String> packages) {
+ ensureNotComplete();
+ moduleToExportedPackages.put(m, unmodifiableSet(packages));
+ return this;
+ }
+
+ /**
+ * Builds the IllegalAccessLogger and sets it as the system-wise logger.
+ */
+ public void complete() {
+ Map<Module, Set<String>> map1 = unmodifiableMap(moduleToConcealedPackages);
+ Map<Module, Set<String>> map2 = unmodifiableMap(moduleToExportedPackages);
+ logger = new IllegalAccessLogger(mode, warningStream, map1, map2);
+ complete = true;
}
}
- // the maximum number of frames to capture
- private static final int MAX_STACK_FRAMES = 32;
-
- // lock to avoid interference when printing stack traces
- private static final Object OUTPUT_LOCK = new Object();
+ // need access to java.lang.Module
+ private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
- // caller -> usages
- private final Map<Class<?>, Set<Usage>> callerToUsages = new WeakHashMap<>();
+ // system-wide IllegalAccessLogger
+ private static volatile IllegalAccessLogger logger;
- // module -> (package name -> CLI option)
- private final Map<Module, Map<String, String>> exported;
- private final Map<Module, Map<String, String>> opened;
+ // logger mode
+ private final Mode mode;
// the print stream to send the warnings
private final PrintStream warningStream;
- private IllegalAccessLogger(Map<Module, Map<String, String>> exported,
- Map<Module, Map<String, String>> opened,
- PrintStream warningStream) {
- this.exported = deepCopy(exported);
- this.opened = deepCopy(opened);
+ // module -> packages open for illegal access
+ private final Map<Module, Set<String>> moduleToConcealedPackages;
+ private final Map<Module, Set<String>> moduleToExportedPackages;
+
+ // caller -> usages
+ private final Map<Class<?>, Usages> callerToUsages = new WeakHashMap<>();
+
+ private IllegalAccessLogger(Mode mode,
+ PrintStream warningStream,
+ Map<Module, Set<String>> moduleToConcealedPackages,
+ Map<Module, Set<String>> moduleToExportedPackages)
+ {
+ this.mode = mode;
this.warningStream = warningStream;
+ this.moduleToConcealedPackages = moduleToConcealedPackages;
+ this.moduleToExportedPackages = moduleToExportedPackages;
}
/**
- * Returns that a Builder that is seeded with the packages known to this logger.
+ * Returns the system-wide IllegalAccessLogger or {@code null} if there is
+ * no logger.
+ */
+ public static IllegalAccessLogger illegalAccessLogger() {
+ return logger;
+ }
+
+ /**
+ * Returns true if the module exports a concealed package for illegal
+ * access.
*/
- public Builder toBuilder() {
- return new Builder(exported, opened);
+ public boolean isExportedForIllegalAccess(Module module, String pn) {
+ Set<String> packages = moduleToConcealedPackages.get(module);
+ if (packages != null && packages.contains(pn))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns true if the module opens a concealed or exported package for
+ * illegal access.
+ */
+ public boolean isOpenForIllegalAccess(Module module, String pn) {
+ if (isExportedForIllegalAccess(module, pn))
+ return true;
+ Set<String> packages = moduleToExportedPackages.get(module);
+ if (packages != null && packages.contains(pn))
+ return true;
+ return false;
}
/**
* Logs access to the member of a target class by a caller class if the class
- * is in a package that is exported via a backdoor mechanism.
+ * is in a package that is exported for illegal access.
*
* The {@code whatSupplier} supplies the message that describes the member.
*/
- public void logIfExportedByBackdoor(Class<?> caller,
- Class<?> target,
- Supplier<String> whatSupplier) {
- Map<String, String> packages = exported.get(target.getModule());
- if (packages != null) {
- String how = packages.get(target.getPackageName());
- if (how != null) {
- log(caller, whatSupplier.get(), how);
+ public void logIfExportedForIllegalAccess(Class<?> caller,
+ Class<?> target,
+ Supplier<String> whatSupplier) {
+ Module targetModule = target.getModule();
+ String targetPackage = target.getPackageName();
+ if (isExportedForIllegalAccess(targetModule, targetPackage)) {
+ Module callerModule = caller.getModule();
+ if (!JLA.isReflectivelyExported(targetModule, targetPackage, callerModule)) {
+ log(caller, whatSupplier.get());
}
}
}
/**
* Logs access to the member of a target class by a caller class if the class
- * is in a package that is opened via a backdoor mechanism.
+ * is in a package that is opened for illegal access.
*
* The {@code what} parameter supplies the message that describes the member.
*/
- public void logIfOpenedByBackdoor(Class<?> caller,
- Class<?> target,
- Supplier<String> whatSupplier) {
- Map<String, String> packages = opened.get(target.getModule());
- if (packages != null) {
- String how = packages.get(target.getPackageName());
- if (how != null) {
- log(caller, whatSupplier.get(), how);
+ public void logIfOpenedForIllegalAccess(Class<?> caller,
+ Class<?> target,
+ Supplier<String> whatSupplier) {
+ Module targetModule = target.getModule();
+ String targetPackage = target.getPackageName();
+ if (isOpenForIllegalAccess(targetModule, targetPackage)) {
+ Module callerModule = caller.getModule();
+ if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
+ log(caller, whatSupplier.get());
+ }
+ }
+ }
+
+ /**
+ * Logs access by caller lookup if the target class is in a package that is
+ * opened for illegal access.
+ */
+ public void logIfOpenedForIllegalAccess(MethodHandles.Lookup caller, Class<?> target) {
+ Module targetModule = target.getModule();
+ String targetPackage = target.getPackageName();
+ if (isOpenForIllegalAccess(targetModule, targetPackage)) {
+ Class<?> callerClass = caller.lookupClass();
+ Module callerModule = callerClass.getModule();
+ if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
+ URL url = codeSource(callerClass);
+ final String source;
+ if (url == null) {
+ source = callerClass.getName();
+ } else {
+ source = callerClass.getName() + " (" + url + ")";
+ }
+ log(callerClass, target.getName(), () ->
+ "WARNING: Illegal reflective access using Lookup on " + source
+ + " to " + target);
}
}
}
/**
* Logs access by a caller class. The {@code what} parameter describes
- * the member is accessed, the {@code how} parameter is the means by which
- * access is allocated (CLI option for example).
+ * the member being accessed.
*/
- private void log(Class<?> caller, String what, String how) {
+ private void log(Class<?> caller, String what) {
log(caller, what, () -> {
- PrivilegedAction<ProtectionDomain> pa = caller::getProtectionDomain;
- CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
- URL url = (cs != null) ? cs.getLocation() : null;
+ URL url = codeSource(caller);
String source = caller.getName();
if (url != null)
source += " (" + url + ")";
- return "WARNING: Illegal access by " + source + " to " + what
- + " (permitted by " + how + ")";
+ return "WARNING: Illegal reflective access by " + source + " to " + what;
});
}
-
- /**
- * Logs access to caller class if the class is in a package that is opened via
- * a backdoor mechanism.
- */
- public void logIfOpenedByBackdoor(MethodHandles.Lookup caller, Class<?> target) {
- Map<String, String> packages = opened.get(target.getModule());
- if (packages != null) {
- String how = packages.get(target.getPackageName());
- if (how != null) {
- log(caller.lookupClass(), target.getName(), () ->
- "WARNING: Illegal access using Lookup on " + caller.lookupClass()
- + " to " + target + " (permitted by " + how + ")");
- }
- }
- }
-
/**
* Log access by a caller. The {@code what} parameter describes the class or
* member that is being accessed. The {@code msgSupplier} supplies the log
@@ -184,53 +278,73 @@
* keys so it can be expunged when the caller is GC'ed/unloaded.
*/
private void log(Class<?> caller, String what, Supplier<String> msgSupplier) {
+ if (mode == Mode.ONESHOT) {
+ synchronized (IllegalAccessLogger.class) {
+ // discard the system wide logger
+ if (logger == null)
+ return;
+ logger = null;
+ }
+ warningStream.println(loudWarning(caller, msgSupplier));
+ return;
+ }
+
// stack trace without the top-most frames in java.base
- List<StackWalker.StackFrame> stack = Holder.STACK_WALKER.walk(s ->
+ List<StackWalker.StackFrame> stack = StackWalkerHolder.INSTANCE.walk(s ->
s.dropWhile(this::isJavaBase)
- .limit(MAX_STACK_FRAMES)
+ .limit(32)
.collect(Collectors.toList())
);
- // check if the access has already been recorded
+ // record usage if this is the first (or not recently recorded)
Usage u = new Usage(what, hash(stack));
- boolean firstUsage;
+ boolean added;
synchronized (this) {
- firstUsage = callerToUsages.computeIfAbsent(caller, k -> new HashSet<>()).add(u);
+ added = callerToUsages.computeIfAbsent(caller, k -> new Usages()).add(u);
}
- // log message if first usage
- if (firstUsage) {
+ // print warning if this is the first (or not a recent) usage
+ if (added) {
String msg = msgSupplier.get();
- if (Holder.PRINT_STACK_TRACE) {
- synchronized (OUTPUT_LOCK) {
- warningStream.println(msg);
- stack.forEach(f -> warningStream.println("\tat " + f));
- }
- } else {
- warningStream.println(msg);
+ if (mode == Mode.DEBUG) {
+ StringBuilder sb = new StringBuilder(msg);
+ stack.forEach(f ->
+ sb.append(System.lineSeparator()).append("\tat " + f)
+ );
+ msg = sb.toString();
}
+ warningStream.println(msg);
}
}
- private static class Usage {
- private final String what;
- private final int stack;
- Usage(String what, int stack) {
- this.what = what;
- this.stack = stack;
- }
- @Override
- public int hashCode() {
- return what.hashCode() ^ stack;
- }
- @Override
- public boolean equals(Object ob) {
- if (ob instanceof Usage) {
- Usage that = (Usage)ob;
- return what.equals(that.what) && stack == (that.stack);
- } else {
- return false;
- }
+ /**
+ * Returns the code source for the given class or null if there is no code source
+ */
+ private URL codeSource(Class<?> clazz) {
+ PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
+ CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
+ return (cs != null) ? cs.getLocation() : null;
+ }
+
+ private String loudWarning(Class<?> caller, Supplier<String> msgSupplier) {
+ StringJoiner sj = new StringJoiner(System.lineSeparator());
+ sj.add("WARNING: An illegal reflective access operation has occurred");
+ sj.add(msgSupplier.get());
+ sj.add("WARNING: Please consider reporting this to the maintainers of "
+ + caller.getName());
+ sj.add("WARNING: Use --illegal-access=warn to enable warnings of further"
+ + " illegal reflective access operations");
+ sj.add("WARNING: All illegal access operations will be denied in a"
+ + " future release");
+ return sj.toString();
+ }
+
+ private static class StackWalkerHolder {
+ static final StackWalker INSTANCE;
+ static {
+ PrivilegedAction<StackWalker> pa = () ->
+ StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ INSTANCE = AccessController.doPrivileged(pa);
}
}
@@ -256,89 +370,39 @@
return hash;
}
- // system-wide IllegalAccessLogger
- private static volatile IllegalAccessLogger logger;
-
- /**
- * Sets the system-wide IllegalAccessLogger
- */
- public static void setIllegalAccessLogger(IllegalAccessLogger l) {
- if (l.exported.isEmpty() && l.opened.isEmpty()) {
- logger = null;
- } else {
- logger = l;
+ private static class Usage {
+ private final String what;
+ private final int stack;
+ Usage(String what, int stack) {
+ this.what = what;
+ this.stack = stack;
+ }
+ @Override
+ public int hashCode() {
+ return what.hashCode() ^ stack;
+ }
+ @Override
+ public boolean equals(Object ob) {
+ if (ob instanceof Usage) {
+ Usage that = (Usage)ob;
+ return what.equals(that.what) && stack == (that.stack);
+ } else {
+ return false;
+ }
}
}
- /**
- * Returns the system-wide IllegalAccessLogger or {@code null} if there is
- * no logger.
- */
- public static IllegalAccessLogger illegalAccessLogger() {
- return logger;
- }
-
- /**
- * A builder for IllegalAccessLogger objects.
- */
- public static class Builder {
- private final Module UNNAMED = BootLoader.getUnnamedModule();
- private Map<Module, Map<String, String>> exported;
- private Map<Module, Map<String, String>> opened;
- private PrintStream warningStream = System.err;
-
- public Builder() { }
-
- public Builder(Map<Module, Map<String, String>> exported,
- Map<Module, Map<String, String>> opened) {
- this.exported = deepCopy(exported);
- this.opened = deepCopy(opened);
- }
-
- public Builder logAccessToExportedPackage(Module m, String pn, String how) {
- if (!m.isExported(pn, UNNAMED)) {
- if (exported == null)
- exported = new HashMap<>();
- exported.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
- }
- return this;
+ @SuppressWarnings("serial")
+ private static class Usages extends LinkedHashMap<Usage, Boolean> {
+ Usages() { }
+ boolean add(Usage u) {
+ return (putIfAbsent(u, Boolean.TRUE) == null);
}
-
- public Builder logAccessToOpenPackage(Module m, String pn, String how) {
- // opens implies exported at run-time.
- logAccessToExportedPackage(m, pn, how);
-
- if (!m.isOpen(pn, UNNAMED)) {
- if (opened == null)
- opened = new HashMap<>();
- opened.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
- }
- return this;
- }
-
- public Builder warningStream(PrintStream warningStream) {
- this.warningStream = Objects.requireNonNull(warningStream);
- return this;
- }
-
- /**
- * Builds the logger.
- */
- public IllegalAccessLogger build() {
- return new IllegalAccessLogger(exported, opened, warningStream);
- }
- }
-
-
- static Map<Module, Map<String, String>> deepCopy(Map<Module, Map<String, String>> map) {
- if (map == null || map.isEmpty()) {
- return new HashMap<>();
- } else {
- Map<Module, Map<String, String>> newMap = new HashMap<>();
- for (Map.Entry<Module, Map<String, String>> e : map.entrySet()) {
- newMap.put(e.getKey(), new HashMap<>(e.getValue()));
- }
- return newMap;
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<Usage, Boolean> oldest) {
+ // prevent map growing too big, say where a utility class
+ // is used by generated code to do illegal access
+ return size() > 16;
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/IllegalAccessMaps.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,128 @@
+/*
+ * 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.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static java.nio.charset.StandardCharsets.*;
+
+/**
+ * Generates the maps of concealed and exported packages to open at run-time.
+ *
+ * This is used at run-time for exploded builds, and at link-time to generate
+ * the maps for the system modules in the run-time image.
+ */
+
+public class IllegalAccessMaps {
+ private final Map<String, Set<String>> concealedPackagesToOpen;
+ private final Map<String, Set<String>> exportedPackagesToOpen;
+
+ private IllegalAccessMaps(Map<String, Set<String>> map1,
+ Map<String, Set<String>> map2) {
+ this.concealedPackagesToOpen = map1;
+ this.exportedPackagesToOpen = map2;
+ }
+
+ /**
+ * Returns the map of concealed packages to open. The map key is the
+ * module name, the value is the set of concealed packages to open.
+ */
+ public Map<String, Set<String>> concealedPackagesToOpen() {
+ return concealedPackagesToOpen;
+ }
+
+ /**
+ * Returns the map of exported packages to open. The map key is the
+ * module name, the value is the set of exported packages to open.
+ */
+ public Map<String, Set<String>> exportedPackagesToOpen() {
+ return exportedPackagesToOpen;
+ }
+
+ /**
+ * Generate the maps of module to concealed and exported packages for
+ * the system modules that are observable with the given module finder.
+ */
+ public static IllegalAccessMaps generate(ModuleFinder finder) {
+ Map<String, ModuleDescriptor> map = new HashMap<>();
+ finder.findAll().stream()
+ .map(ModuleReference::descriptor)
+ .forEach(md -> md.packages().forEach(pn -> map.putIfAbsent(pn, md)));
+
+ Map<String, Set<String>> concealedPackagesToOpen = new HashMap<>();
+ Map<String, Set<String>> exportedPackagesToOpen = new HashMap<>();
+
+ String rn = "jdk8_packages.dat";
+ InputStream in = IllegalAccessMaps.class.getResourceAsStream(rn);
+ if (in == null) {
+ throw new InternalError(rn + " not found");
+ }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(in, UTF_8))) {
+ br.lines()
+ .filter(line -> !line.isEmpty() && !line.startsWith("#"))
+ .forEach(pn -> {
+ ModuleDescriptor descriptor = map.get(pn);
+ if (descriptor != null && !isOpen(descriptor, pn)) {
+ String name = descriptor.name();
+ if (isExported(descriptor, pn)) {
+ exportedPackagesToOpen.computeIfAbsent(name,
+ k -> new HashSet<>()).add(pn);
+ } else {
+ concealedPackagesToOpen.computeIfAbsent(name,
+ k -> new HashSet<>()).add(pn);
+ }
+ }
+ });
+
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+
+ return new IllegalAccessMaps(concealedPackagesToOpen, exportedPackagesToOpen);
+ }
+
+ private static boolean isExported(ModuleDescriptor descriptor, String pn) {
+ return descriptor.exports()
+ .stream()
+ .anyMatch(e -> e.source().equals(pn) && !e.isQualified());
+ }
+
+ private static boolean isOpen(ModuleDescriptor descriptor, String pn) {
+ return descriptor.opens()
+ .stream()
+ .anyMatch(e -> e.source().equals(pn) && !e.isQualified());
+ }
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Fri Jun 16 09:20:39 2017 -0700
@@ -39,14 +39,17 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
+import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
@@ -59,7 +62,7 @@
* -m and --add-modules options. The modules are located on a module path that
* is constructed from the upgrade module path, system modules, and application
* module path. The Configuration is instantiated as the boot layer with each
- * module in the the configuration defined to one of the built-in class loaders.
+ * module in the the configuration defined to a class loader.
*/
public final class ModuleBootstrap {
@@ -119,20 +122,20 @@
*/
public static ModuleLayer boot() {
- long t0 = System.nanoTime();
+ // Step 1: Locate system modules (may be patched)
- // system modules (may be patched)
+ long t1 = System.nanoTime();
ModuleFinder systemModules = ModuleFinder.ofSystem();
-
- PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
+ PerfCounters.systemModulesTime.addElapsedTimeFrom(t1);
- long t1 = System.nanoTime();
+ // Step 2: Define and load java.base. This patches all classes loaded
+ // to date so that they are members of java.base. Once java.base is
+ // loaded then resources in java.base are available for error messages
+ // needed from here on.
- // Once we have the system modules then we define the base module to
- // the VM. We do this here so that java.base is defined as early as
- // possible and also that resources in the base module can be located
- // for error messages that may happen from here on.
+ long t2 = System.nanoTime();
+
ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
if (base == null)
throw new InternalError(JAVA_BASE + " not found");
@@ -142,15 +145,23 @@
BootLoader.loadModule(base);
Modules.defineModule(null, base.descriptor(), baseUri);
- PerfCounters.defineBaseTime.addElapsedTimeFrom(t1);
+ PerfCounters.defineBaseTime.addElapsedTimeFrom(t2);
+
- // special mode to boot with only java.base, ignores other options
+ // Step 2a: If --validate-modules is specified then the VM needs to
+ // start with only java.base, all other options are ignored.
+
String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
if (propValue != null) {
return createMinimalBootLayer();
}
- long t2 = System.nanoTime();
+
+ // Step 3: Construct the module path and the set of root modules to
+ // resolve. If --limit-modules is specified then it limits the set
+ // modules that are observable.
+
+ long t3 = System.nanoTime();
// --upgrade-module-path option specified to launcher
ModuleFinder upgradeModulePath
@@ -269,10 +280,13 @@
.forEach(mn -> roots.add(mn));
}
- PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t2);
+ PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t3);
- long t3 = System.nanoTime();
+ // Step 4: Resolve the root modules, with service binding, to create
+ // the configuration for the boot layer.
+
+ long t4 = System.nanoTime();
// determine if post resolution checks are needed
boolean needPostResolutionChecks = true;
@@ -295,11 +309,17 @@
needPostResolutionChecks,
traceOutput);
- // time to create configuration
- PerfCounters.resolveTime.addElapsedTimeFrom(t3);
+ PerfCounters.resolveTime.addElapsedTimeFrom(t4);
+
- // check module names and incubating status
- checkModuleNamesAndStatus(cf);
+ // Step 5: Map the modules in the configuration to class loaders.
+ // The static configuration provides the mapping of standard and JDK
+ // modules to the boot and platform loaders. All other modules (JDK
+ // tool modules, and both explicit and automatic modules on the
+ // application module path) are defined to the application class
+ // loader.
+
+ long t5 = System.nanoTime();
// mapping of modules to class loaders
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
@@ -312,11 +332,9 @@
String name = mref.descriptor().name();
ClassLoader cl = clf.apply(name);
if (cl == null) {
-
if (upgradeModulePath != null
&& upgradeModulePath.find(name).isPresent())
fail(name + ": cannot be loaded from upgrade module path");
-
if (!systemModules.find(name).isPresent())
fail(name + ": cannot be loaded from application module path");
}
@@ -330,55 +348,38 @@
}
}
- // if needed check that there are no split packages in the set of
- // resolved modules for the boot layer
+ // check for split packages in the modules mapped to the built-in loaders
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
- Map<String, String> packageToModule = new HashMap<>();
- for (ResolvedModule resolvedModule : cf.modules()) {
- ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
- String name = descriptor.name();
- for (String p : descriptor.packages()) {
- String other = packageToModule.putIfAbsent(p, name);
- if (other != null) {
- String msg = "Package " + p + " in both module "
- + name + " and module " + other;
- throw new LayerInstantiationException(msg);
- }
- }
- }
+ checkSplitPackages(cf, clf);
}
- long t4 = System.nanoTime();
-
- // define modules to VM/runtime
- ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
-
- PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
-
-
- long t5 = System.nanoTime();
-
- // define the module to its class loader, except java.base
- for (ResolvedModule resolvedModule : cf.modules()) {
- ModuleReference mref = resolvedModule.reference();
- String name = mref.descriptor().name();
- ClassLoader cl = clf.apply(name);
- if (cl == null) {
- if (!name.equals(JAVA_BASE)) BootLoader.loadModule(mref);
- } else {
- ((BuiltinClassLoader)cl).loadModule(mref);
- }
- }
+ // load/register the modules with the built-in class loaders
+ loadModules(cf, clf);
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
- // --add-reads, --add-exports/--add-opens
+ // Step 6: Define all modules to the VM
+
+ long t6 = System.nanoTime();
+ ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
+ PerfCounters.layerCreateTime.addElapsedTimeFrom(t6);
+
+
+ // Step 7: Miscellaneous
+
+ // check incubating status
+ checkIncubatingStatus(cf);
+
+ // --add-reads, --add-exports/--add-opens, and -illegal-access
+ long t7 = System.nanoTime();
addExtraReads(bootLayer);
- addExtraExportsAndOpens(bootLayer);
+ boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
+ addIllegalAccess(bootLayer, upgradeModulePath, extraExportsOrOpens);
+ PerfCounters.adjustModulesTime.addElapsedTimeFrom(t7);
// total time to initialize
- PerfCounters.bootstrapTime.addElapsedTimeFrom(t0);
+ PerfCounters.bootstrapTime.addElapsedTimeFrom(t1);
return bootLayer;
}
@@ -398,6 +399,51 @@
}
/**
+ * Load/register the modules to the built-in class loaders.
+ */
+ private static void loadModules(Configuration cf,
+ Function<String, ClassLoader> clf) {
+ for (ResolvedModule resolvedModule : cf.modules()) {
+ ModuleReference mref = resolvedModule.reference();
+ String name = resolvedModule.name();
+ ClassLoader loader = clf.apply(name);
+ if (loader == null) {
+ // skip java.base as it is already loaded
+ if (!name.equals(JAVA_BASE)) {
+ BootLoader.loadModule(mref);
+ }
+ } else if (loader instanceof BuiltinClassLoader) {
+ ((BuiltinClassLoader) loader).loadModule(mref);
+ }
+ }
+ }
+
+ /**
+ * Checks for split packages between modules defined to the built-in class
+ * loaders.
+ */
+ private static void checkSplitPackages(Configuration cf,
+ Function<String, ClassLoader> clf) {
+ Map<String, String> packageToModule = new HashMap<>();
+ for (ResolvedModule resolvedModule : cf.modules()) {
+ ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
+ String name = descriptor.name();
+ ClassLoader loader = clf.apply(name);
+ if (loader == null || loader instanceof BuiltinClassLoader) {
+ for (String p : descriptor.packages()) {
+ String other = packageToModule.putIfAbsent(p, name);
+ if (other != null) {
+ String msg = "Package " + p + " in both module "
+ + name + " and module " + other;
+ throw new LayerInstantiationException(msg);
+ }
+ }
+ }
+
+ }
+ }
+
+ /**
* Returns a ModuleFinder that limits observability to the given root
* modules, their transitive dependences, plus a set of other modules.
*/
@@ -458,15 +504,14 @@
}
}
-
/**
* Initialize the module patcher for the initial configuration passed on the
* value of the --patch-module options.
*/
private static ModulePatcher initModulePatcher() {
Map<String, List<String>> map = decode("jdk.module.patch.",
- File.pathSeparator,
- false);
+ File.pathSeparator,
+ false);
return new ModulePatcher(map);
}
@@ -538,38 +583,27 @@
* Process the --add-exports and --add-opens options to export/open
* additional packages specified on the command-line.
*/
- private static void addExtraExportsAndOpens(ModuleLayer bootLayer) {
+ private static boolean addExtraExportsAndOpens(ModuleLayer bootLayer) {
+ boolean extraExportsOrOpens = false;
+
// --add-exports
String prefix = "jdk.module.addexports.";
Map<String, List<String>> extraExports = decode(prefix);
if (!extraExports.isEmpty()) {
addExtraExportsOrOpens(bootLayer, extraExports, false);
+ extraExportsOrOpens = true;
}
+
// --add-opens
prefix = "jdk.module.addopens.";
Map<String, List<String>> extraOpens = decode(prefix);
if (!extraOpens.isEmpty()) {
addExtraExportsOrOpens(bootLayer, extraOpens, true);
+ extraExportsOrOpens = true;
}
- // --permit-illegal-access
- if (getAndRemoveProperty("jdk.module.permitIllegalAccess") != null) {
- warn("--permit-illegal-access will be removed in the next major release");
- IllegalAccessLogger.Builder builder = new IllegalAccessLogger.Builder();
- Module unnamed = BootLoader.getUnnamedModule();
- bootLayer.modules().stream().forEach(m -> {
- m.getDescriptor()
- .packages()
- .stream()
- .filter(pn -> !m.isOpen(pn, unnamed)) // skip if opened by --add-opens
- .forEach(pn -> {
- builder.logAccessToOpenPackage(m, pn, "--permit-illegal-access");
- Modules.addOpensToAllUnnamed(m, pn);
- });
- });
- IllegalAccessLogger.setIllegalAccessLogger(builder.build());
- }
+ return extraExportsOrOpens;
}
private static void addExtraExportsOrOpens(ModuleLayer bootLayer,
@@ -639,6 +673,102 @@
}
/**
+ * Process the --illegal-access option (and its default) to open packages
+ * of system modules in the boot layer to code in unnamed modules.
+ */
+ private static void addIllegalAccess(ModuleLayer bootLayer,
+ ModuleFinder upgradeModulePath,
+ boolean extraExportsOrOpens) {
+ String value = getAndRemoveProperty("jdk.module.illegalAccess");
+ IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
+ if (value != null) {
+ switch (value) {
+ case "deny":
+ return;
+ case "permit":
+ break;
+ case "warn":
+ mode = IllegalAccessLogger.Mode.WARN;
+ break;
+ case "debug":
+ mode = IllegalAccessLogger.Mode.DEBUG;
+ break;
+ default:
+ fail("Value specified to --illegal-access not recognized:"
+ + " '" + value + "'");
+ return;
+ }
+ }
+ IllegalAccessLogger.Builder builder
+ = new IllegalAccessLogger.Builder(mode, System.err);
+
+ Map<String, Set<String>> map1 = SystemModules.concealedPackagesToOpen();
+ Map<String, Set<String>> map2 = SystemModules.exportedPackagesToOpen();
+ if (map1.isEmpty() && map2.isEmpty()) {
+ // need to generate maps when on exploded build
+ IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
+ map1 = maps.concealedPackagesToOpen();
+ map2 = maps.exportedPackagesToOpen();
+ }
+
+ // open specific packages in the system modules
+ for (Module m : bootLayer.modules()) {
+ ModuleDescriptor descriptor = m.getDescriptor();
+ String name = m.getName();
+
+ // skip open modules
+ if (descriptor.isOpen()) {
+ continue;
+ }
+
+ // skip modules loaded from the upgrade module path
+ if (upgradeModulePath != null
+ && upgradeModulePath.find(name).isPresent()) {
+ continue;
+ }
+
+ Set<String> concealedPackages = map1.getOrDefault(name, Set.of());
+ Set<String> exportedPackages = map2.getOrDefault(name, Set.of());
+
+ // refresh the set of concealed and exported packages if needed
+ if (extraExportsOrOpens) {
+ concealedPackages = new HashSet<>(concealedPackages);
+ exportedPackages = new HashSet<>(exportedPackages);
+ Iterator<String> iterator = concealedPackages.iterator();
+ while (iterator.hasNext()) {
+ String pn = iterator.next();
+ if (m.isExported(pn, BootLoader.getUnnamedModule())) {
+ // concealed package is exported to ALL-UNNAMED
+ iterator.remove();
+ exportedPackages.add(pn);
+ }
+ }
+ iterator = exportedPackages.iterator();
+ while (iterator.hasNext()) {
+ String pn = iterator.next();
+ if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
+ // exported package is opened to ALL-UNNAMED
+ iterator.remove();
+ }
+ }
+ }
+
+ // log reflective access to all types in concealed packages
+ builder.logAccessToConcealedPackages(m, concealedPackages);
+
+ // log reflective access to non-public members/types in exported packages
+ builder.logAccessToExportedPackages(m, exportedPackages);
+
+ // open the packages to unnamed modules
+ JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+ jla.addOpensToAllUnnamed(m, concat(concealedPackages.iterator(),
+ exportedPackages.iterator()));
+ }
+
+ builder.complete();
+ }
+
+ /**
* Decodes the values of --add-reads, -add-exports, --add-opens or
* --patch-modules options that are encoded in system properties.
*
@@ -708,17 +838,16 @@
}
/**
- * Checks the names and resolution bit of each module in the configuration,
- * emitting warnings if needed.
+ * Checks incubating status of modules in the configuration
*/
- private static void checkModuleNamesAndStatus(Configuration cf) {
+ private static void checkIncubatingStatus(Configuration cf) {
String incubating = null;
- for (ResolvedModule rm : cf.modules()) {
- ModuleReference mref = rm.reference();
- String mn = mref.descriptor().name();
+ for (ResolvedModule resolvedModule : cf.modules()) {
+ ModuleReference mref = resolvedModule.reference();
// emit warning if the WARN_INCUBATING module resolution bit set
if (ModuleResolution.hasIncubatingWarning(mref)) {
+ String mn = mref.descriptor().name();
if (incubating == null) {
incubating = mn;
} else {
@@ -777,6 +906,21 @@
}
}
+ static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return iterator1.hasNext() || iterator2.hasNext();
+ }
+ @Override
+ public T next() {
+ if (iterator1.hasNext()) return iterator1.next();
+ if (iterator2.hasNext()) return iterator2.next();
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
static class PerfCounters {
static PerfCounter systemModulesTime
@@ -791,6 +935,8 @@
= PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
static PerfCounter loadModulesTime
= PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
+ static PerfCounter adjustModulesTime
+ = PerfCounter.newPerfCounter("jdk.module.bootstrap.adjustModulesTime");
static PerfCounter bootstrapTime
= PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Fri Jun 16 09:20:39 2017 -0700
@@ -35,6 +35,7 @@
import java.lang.module.FindException;
import java.lang.module.InvalidModuleDescriptorException;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.net.URI;
@@ -404,6 +405,9 @@
private static final String SERVICES_PREFIX = "META-INF/services/";
+ private static final Attributes.Name AUTOMATIC_MODULE_NAME
+ = new Attributes.Name("Automatic-Module-Name");
+
/**
* Returns the service type corresponding to the name of a services
* configuration file if it is a legal type name.
@@ -445,48 +449,68 @@
/**
* Treat the given JAR file as a module as follows:
*
- * 1. The module name (and optionally the version) is derived from the file
- * name of the JAR file
- * 2. All packages are derived from the .class files in the JAR file
- * 3. The contents of any META-INF/services configuration files are mapped
+ * 1. The value of the Automatic-Module-Name attribute is the module name
+ * 2. The version, and the module name when the Automatic-Module-Name
+ * attribute is not present, is derived from the file ame of the JAR file
+ * 3. All packages are derived from the .class files in the JAR file
+ * 4. The contents of any META-INF/services configuration files are mapped
* to "provides" declarations
- * 4. The Main-Class attribute in the main attributes of the JAR manifest
+ * 5. The Main-Class attribute in the main attributes of the JAR manifest
* is mapped to the module descriptor mainClass if possible
*/
private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
throws IOException
{
- // Derive module name and version from JAR file name
+ // Read Automatic-Module-Name attribute if present
+ Manifest man = jf.getManifest();
+ Attributes attrs = null;
+ String moduleName = null;
+ if (man != null) {
+ attrs = man.getMainAttributes();
+ if (attrs != null) {
+ moduleName = attrs.getValue(AUTOMATIC_MODULE_NAME);
+ }
+ }
+ // Derive the version, and the module name if needed, from JAR file name
String fn = jf.getName();
int i = fn.lastIndexOf(File.separator);
if (i != -1)
- fn = fn.substring(i+1);
+ fn = fn.substring(i + 1);
- // drop .jar
- String mn = fn.substring(0, fn.length()-4);
+ // drop ".jar"
+ String name = fn.substring(0, fn.length() - 4);
String vs = null;
// find first occurrence of -${NUMBER}. or -${NUMBER}$
- Matcher matcher = Patterns.DASH_VERSION.matcher(mn);
+ Matcher matcher = Patterns.DASH_VERSION.matcher(name);
if (matcher.find()) {
int start = matcher.start();
// attempt to parse the tail as a version string
try {
- String tail = mn.substring(start+1);
+ String tail = name.substring(start + 1);
ModuleDescriptor.Version.parse(tail);
vs = tail;
} catch (IllegalArgumentException ignore) { }
- mn = mn.substring(0, start);
+ name = name.substring(0, start);
}
- // finally clean up the module name
- mn = cleanModuleName(mn);
+ // Create builder, using the name derived from file name when
+ // Automatic-Module-Name not present
+ Builder builder;
+ if (moduleName != null) {
+ try {
+ builder = ModuleDescriptor.newAutomaticModule(moduleName);
+ } catch (IllegalArgumentException e) {
+ throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
+ }
+ } else {
+ builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
+ }
- // Builder throws IAE if module name is empty or invalid
- ModuleDescriptor.Builder builder = ModuleDescriptor.newAutomaticModule(mn);
+ // module version if present
if (vs != null)
builder.version(vs);
@@ -541,9 +565,7 @@
}
// Main-Class attribute if it exists
- Manifest man = jf.getManifest();
- if (man != null) {
- Attributes attrs = man.getMainAttributes();
+ if (attrs != null) {
String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
mainClass = mainClass.replace("/", ".");
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Fri Jun 16 09:20:39 2017 -0700
@@ -41,6 +41,10 @@
public class ModuleReferenceImpl extends ModuleReference {
+ // location of module
+ private final URI location;
+
+ // the module reader
private final Supplier<ModuleReader> readerSupplier;
// non-null if the module is patched
@@ -74,6 +78,7 @@
ModuleResolution moduleResolution)
{
super(descriptor, Objects.requireNonNull(location));
+ this.location = location;
this.readerSupplier = readerSupplier;
this.patcher = patcher;
this.target = target;
@@ -148,7 +153,7 @@
int hc = hash;
if (hc == 0) {
hc = descriptor().hashCode();
- hc = 43 * hc + Objects.hashCode(location());
+ hc = 43 * hc + Objects.hashCode(location);
hc = 43 * hc + Objects.hashCode(patcher);
if (hc == 0)
hc = -1;
@@ -169,7 +174,7 @@
// when the modules have equal module descriptors, are at the
// same location, and are patched by the same patcher.
return Objects.equals(this.descriptor(), that.descriptor())
- && Objects.equals(this.location(), that.location())
+ && Objects.equals(this.location, that.location)
&& Objects.equals(this.patcher, that.patcher);
}
@@ -179,7 +184,7 @@
sb.append("[module ");
sb.append(descriptor().name());
sb.append(", location=");
- sb.append(location().orElseThrow(() -> new InternalError()));
+ sb.append(location);
if (isPatched()) sb.append(" (patched)");
sb.append("]");
return sb.toString();
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Fri Jun 16 09:20:39 2017 -0700
@@ -136,10 +136,12 @@
public static void addProvides(Module m, Class<?> service, Class<?> impl) {
ModuleLayer layer = m.getLayer();
- if (layer == null || layer == ModuleLayer.boot()) {
+ PrivilegedAction<ClassLoader> pa = m::getClassLoader;
+ ClassLoader loader = AccessController.doPrivileged(pa);
+
+ ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
+ if (layer == null || loader == null || loader == platformClassLoader) {
// update ClassLoader catalog
- PrivilegedAction<ClassLoader> pa = m::getClassLoader;
- ClassLoader loader = AccessController.doPrivileged(pa);
ServicesCatalog catalog;
if (loader == null) {
catalog = BootLoader.getServicesCatalog();
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModules.java Fri Jun 16 09:20:39 2017 -0700
@@ -26,6 +26,9 @@
package jdk.internal.module;
import java.lang.module.ModuleDescriptor;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
/**
* SystemModules class will be generated at link time to create
@@ -57,8 +60,7 @@
public static int PACKAGES_IN_BOOT_LAYER = 1024;
/**
- * @return {@code false} if there are no split packages in the run-time
- * image, {@code true} if there are or if it's not been checked.
+ * Return true if there are no split packages in the run-time image.
*/
public static boolean hasSplitPackages() {
return true;
@@ -98,4 +100,20 @@
public static ModuleResolution[] moduleResolutions() {
throw new InternalError("expected to be overridden at link time");
}
+
+ /**
+ * Returns the map of module concealed packages to open. The map key is the
+ * module name, the value is the set of concealed packages to open.
+ */
+ public static Map<String, Set<String>> concealedPackagesToOpen() {
+ return Collections.emptyMap();
+ }
+
+ /**
+ * Returns the map of module exported packages to open. The map key is the
+ * module name, the value is the set of exported packages to open.
+ */
+ public static Map<String, Set<String>> exportedPackagesToOpen() {
+ return Collections.emptyMap();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/jdk8_packages.dat Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,1340 @@
+# 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.
+#
+apple.applescript
+apple.laf
+apple.launcher
+apple.security
+com.apple.concurrent
+com.apple.eawt
+com.apple.eawt.event
+com.apple.eio
+com.apple.laf
+com.apple.laf.resources
+com.oracle.jrockit.jfr
+com.oracle.jrockit.jfr.client
+com.oracle.jrockit.jfr.management
+com.oracle.security.ucrypto
+com.oracle.util
+com.oracle.webservices.internal.api
+com.oracle.webservices.internal.api.databinding
+com.oracle.webservices.internal.api.message
+com.oracle.webservices.internal.impl.encoding
+com.oracle.webservices.internal.impl.internalspi.encoding
+com.oracle.xmlns.internal.webservices.jaxws_databinding
+com.sun.accessibility.internal.resources
+com.sun.activation.registries
+com.sun.awt
+com.sun.beans
+com.sun.beans.decoder
+com.sun.beans.editors
+com.sun.beans.finder
+com.sun.beans.infos
+com.sun.beans.util
+com.sun.codemodel.internal
+com.sun.codemodel.internal.fmt
+com.sun.codemodel.internal.util
+com.sun.codemodel.internal.writer
+com.sun.corba.se.impl.activation
+com.sun.corba.se.impl.copyobject
+com.sun.corba.se.impl.corba
+com.sun.corba.se.impl.dynamicany
+com.sun.corba.se.impl.encoding
+com.sun.corba.se.impl.interceptors
+com.sun.corba.se.impl.io
+com.sun.corba.se.impl.ior
+com.sun.corba.se.impl.ior.iiop
+com.sun.corba.se.impl.javax.rmi
+com.sun.corba.se.impl.javax.rmi.CORBA
+com.sun.corba.se.impl.legacy.connection
+com.sun.corba.se.impl.logging
+com.sun.corba.se.impl.monitoring
+com.sun.corba.se.impl.naming.cosnaming
+com.sun.corba.se.impl.naming.namingutil
+com.sun.corba.se.impl.naming.pcosnaming
+com.sun.corba.se.impl.oa
+com.sun.corba.se.impl.oa.poa
+com.sun.corba.se.impl.oa.toa
+com.sun.corba.se.impl.orb
+com.sun.corba.se.impl.orbutil
+com.sun.corba.se.impl.orbutil.closure
+com.sun.corba.se.impl.orbutil.concurrent
+com.sun.corba.se.impl.orbutil.fsm
+com.sun.corba.se.impl.orbutil.graph
+com.sun.corba.se.impl.orbutil.threadpool
+com.sun.corba.se.impl.presentation.rmi
+com.sun.corba.se.impl.protocol
+com.sun.corba.se.impl.protocol.giopmsgheaders
+com.sun.corba.se.impl.resolver
+com.sun.corba.se.impl.transport
+com.sun.corba.se.impl.util
+com.sun.corba.se.internal.CosNaming
+com.sun.corba.se.internal.Interceptors
+com.sun.corba.se.internal.POA
+com.sun.corba.se.internal.corba
+com.sun.corba.se.internal.iiop
+com.sun.corba.se.org.omg.CORBA
+com.sun.corba.se.pept.broker
+com.sun.corba.se.pept.encoding
+com.sun.corba.se.pept.protocol
+com.sun.corba.se.pept.transport
+com.sun.corba.se.spi.activation
+com.sun.corba.se.spi.activation.InitialNameServicePackage
+com.sun.corba.se.spi.activation.LocatorPackage
+com.sun.corba.se.spi.activation.RepositoryPackage
+com.sun.corba.se.spi.copyobject
+com.sun.corba.se.spi.encoding
+com.sun.corba.se.spi.extension
+com.sun.corba.se.spi.ior
+com.sun.corba.se.spi.ior.iiop
+com.sun.corba.se.spi.legacy.connection
+com.sun.corba.se.spi.legacy.interceptor
+com.sun.corba.se.spi.logging
+com.sun.corba.se.spi.monitoring
+com.sun.corba.se.spi.oa
+com.sun.corba.se.spi.orb
+com.sun.corba.se.spi.orbutil.closure
+com.sun.corba.se.spi.orbutil.fsm
+com.sun.corba.se.spi.orbutil.proxy
+com.sun.corba.se.spi.orbutil.threadpool
+com.sun.corba.se.spi.presentation.rmi
+com.sun.corba.se.spi.protocol
+com.sun.corba.se.spi.resolver
+com.sun.corba.se.spi.servicecontext
+com.sun.corba.se.spi.transport
+com.sun.crypto.provider
+com.sun.demo.jvmti.hprof
+com.sun.deploy.uitoolkit.impl.fx
+com.sun.deploy.uitoolkit.impl.fx.ui
+com.sun.deploy.uitoolkit.impl.fx.ui.resources
+com.sun.glass.events
+com.sun.glass.events.mac
+com.sun.glass.ui
+com.sun.glass.ui.delegate
+com.sun.glass.ui.gtk
+com.sun.glass.ui.mac
+com.sun.glass.ui.win
+com.sun.glass.utils
+com.sun.image.codec.jpeg
+com.sun.imageio.plugins.bmp
+com.sun.imageio.plugins.common
+com.sun.imageio.plugins.gif
+com.sun.imageio.plugins.jpeg
+com.sun.imageio.plugins.png
+com.sun.imageio.plugins.wbmp
+com.sun.imageio.spi
+com.sun.imageio.stream
+com.sun.istack.internal
+com.sun.istack.internal.localization
+com.sun.istack.internal.logging
+com.sun.istack.internal.tools
+com.sun.jarsigner
+com.sun.java.accessibility
+com.sun.java.accessibility.util
+com.sun.java.accessibility.util.java.awt
+com.sun.java.browser.dom
+com.sun.java.browser.net
+com.sun.java.swing
+com.sun.java.swing.plaf.gtk
+com.sun.java.swing.plaf.gtk.resources
+com.sun.java.swing.plaf.motif
+com.sun.java.swing.plaf.motif.resources
+com.sun.java.swing.plaf.nimbus
+com.sun.java.swing.plaf.windows
+com.sun.java.swing.plaf.windows.resources
+com.sun.java.util.jar.pack
+com.sun.java_cup.internal.runtime
+com.sun.javadoc
+com.sun.javafx
+com.sun.javafx.animation
+com.sun.javafx.applet
+com.sun.javafx.application
+com.sun.javafx.beans
+com.sun.javafx.beans.event
+com.sun.javafx.binding
+com.sun.javafx.charts
+com.sun.javafx.collections
+com.sun.javafx.css
+com.sun.javafx.css.converters
+com.sun.javafx.css.parser
+com.sun.javafx.cursor
+com.sun.javafx.effect
+com.sun.javafx.embed
+com.sun.javafx.event
+com.sun.javafx.font
+com.sun.javafx.font.coretext
+com.sun.javafx.font.directwrite
+com.sun.javafx.font.freetype
+com.sun.javafx.font.t2k
+com.sun.javafx.fxml
+com.sun.javafx.fxml.builder
+com.sun.javafx.fxml.expression
+com.sun.javafx.geom
+com.sun.javafx.geom.transform
+com.sun.javafx.geometry
+com.sun.javafx.iio
+com.sun.javafx.iio.bmp
+com.sun.javafx.iio.common
+com.sun.javafx.iio.gif
+com.sun.javafx.iio.ios
+com.sun.javafx.iio.jpeg
+com.sun.javafx.iio.png
+com.sun.javafx.image
+com.sun.javafx.image.impl
+com.sun.javafx.jmx
+com.sun.javafx.logging
+com.sun.javafx.media
+com.sun.javafx.menu
+com.sun.javafx.perf
+com.sun.javafx.print
+com.sun.javafx.property
+com.sun.javafx.property.adapter
+com.sun.javafx.robot
+com.sun.javafx.robot.impl
+com.sun.javafx.runtime
+com.sun.javafx.runtime.async
+com.sun.javafx.runtime.eula
+com.sun.javafx.scene
+com.sun.javafx.scene.control
+com.sun.javafx.scene.control.behavior
+com.sun.javafx.scene.control.skin
+com.sun.javafx.scene.control.skin.resources
+com.sun.javafx.scene.input
+com.sun.javafx.scene.layout.region
+com.sun.javafx.scene.paint
+com.sun.javafx.scene.shape
+com.sun.javafx.scene.text
+com.sun.javafx.scene.transform
+com.sun.javafx.scene.traversal
+com.sun.javafx.scene.web
+com.sun.javafx.scene.web.behavior
+com.sun.javafx.scene.web.skin
+com.sun.javafx.sg.prism
+com.sun.javafx.sg.prism.web
+com.sun.javafx.stage
+com.sun.javafx.text
+com.sun.javafx.tk
+com.sun.javafx.tk.quantum
+com.sun.javafx.util
+com.sun.javafx.webkit
+com.sun.javafx.webkit.drt
+com.sun.javafx.webkit.prism
+com.sun.javafx.webkit.prism.theme
+com.sun.javafx.webkit.theme
+com.sun.jdi
+com.sun.jdi.connect
+com.sun.jdi.connect.spi
+com.sun.jdi.event
+com.sun.jdi.request
+com.sun.jmx.defaults
+com.sun.jmx.interceptor
+com.sun.jmx.mbeanserver
+com.sun.jmx.remote.internal
+com.sun.jmx.remote.protocol.iiop
+com.sun.jmx.remote.protocol.rmi
+com.sun.jmx.remote.security
+com.sun.jmx.remote.util
+com.sun.jmx.snmp
+com.sun.jmx.snmp.IPAcl
+com.sun.jmx.snmp.agent
+com.sun.jmx.snmp.daemon
+com.sun.jmx.snmp.defaults
+com.sun.jmx.snmp.internal
+com.sun.jmx.snmp.mpm
+com.sun.jmx.snmp.tasks
+com.sun.jndi.cosnaming
+com.sun.jndi.dns
+com.sun.jndi.ldap
+com.sun.jndi.ldap.ext
+com.sun.jndi.ldap.pool
+com.sun.jndi.ldap.sasl
+com.sun.jndi.rmi.registry
+com.sun.jndi.toolkit.corba
+com.sun.jndi.toolkit.ctx
+com.sun.jndi.toolkit.dir
+com.sun.jndi.toolkit.url
+com.sun.jndi.url.corbaname
+com.sun.jndi.url.dns
+com.sun.jndi.url.iiop
+com.sun.jndi.url.iiopname
+com.sun.jndi.url.ldap
+com.sun.jndi.url.ldaps
+com.sun.jndi.url.rmi
+com.sun.management
+com.sun.management.jmx
+com.sun.media.jfxmedia
+com.sun.media.jfxmedia.control
+com.sun.media.jfxmedia.effects
+com.sun.media.jfxmedia.events
+com.sun.media.jfxmedia.locator
+com.sun.media.jfxmedia.logging
+com.sun.media.jfxmedia.track
+com.sun.media.jfxmediaimpl
+com.sun.media.jfxmediaimpl.platform
+com.sun.media.jfxmediaimpl.platform.gstreamer
+com.sun.media.jfxmediaimpl.platform.ios
+com.sun.media.jfxmediaimpl.platform.java
+com.sun.media.jfxmediaimpl.platform.osx
+com.sun.media.sound
+com.sun.naming.internal
+com.sun.net.httpserver
+com.sun.net.httpserver.spi
+com.sun.net.ssl
+com.sun.net.ssl.internal.ssl
+com.sun.net.ssl.internal.www.protocol.https
+com.sun.nio.file
+com.sun.nio.sctp
+com.sun.nio.zipfs
+com.sun.openpisces
+com.sun.org.apache.bcel.internal
+com.sun.org.apache.bcel.internal.classfile
+com.sun.org.apache.bcel.internal.generic
+com.sun.org.apache.bcel.internal.util
+com.sun.org.apache.regexp.internal
+com.sun.org.apache.xalan.internal
+com.sun.org.apache.xalan.internal.extensions
+com.sun.org.apache.xalan.internal.lib
+com.sun.org.apache.xalan.internal.res
+com.sun.org.apache.xalan.internal.templates
+com.sun.org.apache.xalan.internal.utils
+com.sun.org.apache.xalan.internal.xslt
+com.sun.org.apache.xalan.internal.xsltc
+com.sun.org.apache.xalan.internal.xsltc.cmdline
+com.sun.org.apache.xalan.internal.xsltc.cmdline.getopt
+com.sun.org.apache.xalan.internal.xsltc.compiler
+com.sun.org.apache.xalan.internal.xsltc.compiler.util
+com.sun.org.apache.xalan.internal.xsltc.dom
+com.sun.org.apache.xalan.internal.xsltc.runtime
+com.sun.org.apache.xalan.internal.xsltc.runtime.output
+com.sun.org.apache.xalan.internal.xsltc.trax
+com.sun.org.apache.xalan.internal.xsltc.util
+com.sun.org.apache.xerces.internal.dom
+com.sun.org.apache.xerces.internal.dom.events
+com.sun.org.apache.xerces.internal.impl
+com.sun.org.apache.xerces.internal.impl.dtd
+com.sun.org.apache.xerces.internal.impl.dtd.models
+com.sun.org.apache.xerces.internal.impl.dv
+com.sun.org.apache.xerces.internal.impl.dv.dtd
+com.sun.org.apache.xerces.internal.impl.dv.util
+com.sun.org.apache.xerces.internal.impl.dv.xs
+com.sun.org.apache.xerces.internal.impl.io
+com.sun.org.apache.xerces.internal.impl.msg
+com.sun.org.apache.xerces.internal.impl.validation
+com.sun.org.apache.xerces.internal.impl.xpath
+com.sun.org.apache.xerces.internal.impl.xpath.regex
+com.sun.org.apache.xerces.internal.impl.xs
+com.sun.org.apache.xerces.internal.impl.xs.identity
+com.sun.org.apache.xerces.internal.impl.xs.models
+com.sun.org.apache.xerces.internal.impl.xs.opti
+com.sun.org.apache.xerces.internal.impl.xs.traversers
+com.sun.org.apache.xerces.internal.impl.xs.util
+com.sun.org.apache.xerces.internal.jaxp
+com.sun.org.apache.xerces.internal.jaxp.datatype
+com.sun.org.apache.xerces.internal.jaxp.validation
+com.sun.org.apache.xerces.internal.parsers
+com.sun.org.apache.xerces.internal.util
+com.sun.org.apache.xerces.internal.utils
+com.sun.org.apache.xerces.internal.xinclude
+com.sun.org.apache.xerces.internal.xni
+com.sun.org.apache.xerces.internal.xni.grammars
+com.sun.org.apache.xerces.internal.xni.parser
+com.sun.org.apache.xerces.internal.xpointer
+com.sun.org.apache.xerces.internal.xs
+com.sun.org.apache.xerces.internal.xs.datatypes
+com.sun.org.apache.xml.internal.dtm
+com.sun.org.apache.xml.internal.dtm.ref
+com.sun.org.apache.xml.internal.dtm.ref.dom2dtm
+com.sun.org.apache.xml.internal.dtm.ref.sax2dtm
+com.sun.org.apache.xml.internal.res
+com.sun.org.apache.xml.internal.resolver
+com.sun.org.apache.xml.internal.resolver.helpers
+com.sun.org.apache.xml.internal.resolver.readers
+com.sun.org.apache.xml.internal.resolver.tools
+com.sun.org.apache.xml.internal.security
+com.sun.org.apache.xml.internal.security.algorithms
+com.sun.org.apache.xml.internal.security.algorithms.implementations
+com.sun.org.apache.xml.internal.security.c14n
+com.sun.org.apache.xml.internal.security.c14n.helper
+com.sun.org.apache.xml.internal.security.c14n.implementations
+com.sun.org.apache.xml.internal.security.encryption
+com.sun.org.apache.xml.internal.security.exceptions
+com.sun.org.apache.xml.internal.security.keys
+com.sun.org.apache.xml.internal.security.keys.content
+com.sun.org.apache.xml.internal.security.keys.content.keyvalues
+com.sun.org.apache.xml.internal.security.keys.content.x509
+com.sun.org.apache.xml.internal.security.keys.keyresolver
+com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations
+com.sun.org.apache.xml.internal.security.keys.storage
+com.sun.org.apache.xml.internal.security.keys.storage.implementations
+com.sun.org.apache.xml.internal.security.signature
+com.sun.org.apache.xml.internal.security.signature.reference
+com.sun.org.apache.xml.internal.security.transforms
+com.sun.org.apache.xml.internal.security.transforms.implementations
+com.sun.org.apache.xml.internal.security.transforms.params
+com.sun.org.apache.xml.internal.security.utils
+com.sun.org.apache.xml.internal.security.utils.resolver
+com.sun.org.apache.xml.internal.security.utils.resolver.implementations
+com.sun.org.apache.xml.internal.serialize
+com.sun.org.apache.xml.internal.serializer
+com.sun.org.apache.xml.internal.serializer.utils
+com.sun.org.apache.xml.internal.utils
+com.sun.org.apache.xml.internal.utils.res
+com.sun.org.apache.xpath.internal
+com.sun.org.apache.xpath.internal.axes
+com.sun.org.apache.xpath.internal.compiler
+com.sun.org.apache.xpath.internal.domapi
+com.sun.org.apache.xpath.internal.functions
+com.sun.org.apache.xpath.internal.jaxp
+com.sun.org.apache.xpath.internal.objects
+com.sun.org.apache.xpath.internal.operations
+com.sun.org.apache.xpath.internal.patterns
+com.sun.org.apache.xpath.internal.res
+com.sun.org.glassfish.external.amx
+com.sun.org.glassfish.external.arc
+com.sun.org.glassfish.external.probe.provider
+com.sun.org.glassfish.external.probe.provider.annotations
+com.sun.org.glassfish.external.statistics
+com.sun.org.glassfish.external.statistics.annotations
+com.sun.org.glassfish.external.statistics.impl
+com.sun.org.glassfish.gmbal
+com.sun.org.glassfish.gmbal.util
+com.sun.org.omg.CORBA
+com.sun.org.omg.CORBA.ValueDefPackage
+com.sun.org.omg.CORBA.portable
+com.sun.org.omg.SendingContext
+com.sun.org.omg.SendingContext.CodeBasePackage
+com.sun.pisces
+com.sun.prism
+com.sun.prism.d3d
+com.sun.prism.es2
+com.sun.prism.image
+com.sun.prism.impl
+com.sun.prism.impl.packrect
+com.sun.prism.impl.paint
+com.sun.prism.impl.ps
+com.sun.prism.impl.shape
+com.sun.prism.j2d
+com.sun.prism.j2d.paint
+com.sun.prism.j2d.print
+com.sun.prism.paint
+com.sun.prism.ps
+com.sun.prism.shader
+com.sun.prism.shape
+com.sun.prism.sw
+com.sun.rmi.rmid
+com.sun.rowset
+com.sun.rowset.internal
+com.sun.rowset.providers
+com.sun.scenario
+com.sun.scenario.animation
+com.sun.scenario.animation.shared
+com.sun.scenario.effect
+com.sun.scenario.effect.impl
+com.sun.scenario.effect.impl.es2
+com.sun.scenario.effect.impl.hw
+com.sun.scenario.effect.impl.hw.d3d
+com.sun.scenario.effect.impl.prism
+com.sun.scenario.effect.impl.prism.ps
+com.sun.scenario.effect.impl.prism.sw
+com.sun.scenario.effect.impl.state
+com.sun.scenario.effect.impl.sw
+com.sun.scenario.effect.impl.sw.java
+com.sun.scenario.effect.impl.sw.sse
+com.sun.scenario.effect.light
+com.sun.security.auth
+com.sun.security.auth.callback
+com.sun.security.auth.login
+com.sun.security.auth.module
+com.sun.security.cert.internal.x509
+com.sun.security.jgss
+com.sun.security.ntlm
+com.sun.security.sasl
+com.sun.security.sasl.digest
+com.sun.security.sasl.gsskerb
+com.sun.security.sasl.ntlm
+com.sun.security.sasl.util
+com.sun.source.doctree
+com.sun.source.tree
+com.sun.source.util
+com.sun.swing.internal.plaf.basic.resources
+com.sun.swing.internal.plaf.metal.resources
+com.sun.swing.internal.plaf.synth.resources
+com.sun.tools.attach
+com.sun.tools.attach.spi
+com.sun.tools.classfile
+com.sun.tools.corba.se.idl
+com.sun.tools.corba.se.idl.constExpr
+com.sun.tools.corba.se.idl.som.cff
+com.sun.tools.corba.se.idl.som.idlemit
+com.sun.tools.corba.se.idl.toJavaPortable
+com.sun.tools.doclets
+com.sun.tools.doclets.formats.html
+com.sun.tools.doclets.formats.html.markup
+com.sun.tools.doclets.formats.html.resources
+com.sun.tools.doclets.internal.toolkit
+com.sun.tools.doclets.internal.toolkit.builders
+com.sun.tools.doclets.internal.toolkit.resources
+com.sun.tools.doclets.internal.toolkit.taglets
+com.sun.tools.doclets.internal.toolkit.util
+com.sun.tools.doclets.internal.toolkit.util.links
+com.sun.tools.doclets.standard
+com.sun.tools.doclint
+com.sun.tools.doclint.resources
+com.sun.tools.example.debug.expr
+com.sun.tools.example.debug.tty
+com.sun.tools.extcheck
+com.sun.tools.hat
+com.sun.tools.hat.internal.model
+com.sun.tools.hat.internal.oql
+com.sun.tools.hat.internal.parser
+com.sun.tools.hat.internal.server
+com.sun.tools.hat.internal.util
+com.sun.tools.internal.jxc
+com.sun.tools.internal.jxc.ap
+com.sun.tools.internal.jxc.api
+com.sun.tools.internal.jxc.api.impl.j2s
+com.sun.tools.internal.jxc.gen.config
+com.sun.tools.internal.jxc.model.nav
+com.sun.tools.internal.ws
+com.sun.tools.internal.ws.api
+com.sun.tools.internal.ws.api.wsdl
+com.sun.tools.internal.ws.processor
+com.sun.tools.internal.ws.processor.generator
+com.sun.tools.internal.ws.processor.model
+com.sun.tools.internal.ws.processor.model.exporter
+com.sun.tools.internal.ws.processor.model.java
+com.sun.tools.internal.ws.processor.model.jaxb
+com.sun.tools.internal.ws.processor.modeler
+com.sun.tools.internal.ws.processor.modeler.annotation
+com.sun.tools.internal.ws.processor.modeler.wsdl
+com.sun.tools.internal.ws.processor.util
+com.sun.tools.internal.ws.resources
+com.sun.tools.internal.ws.spi
+com.sun.tools.internal.ws.util
+com.sun.tools.internal.ws.util.xml
+com.sun.tools.internal.ws.wscompile
+com.sun.tools.internal.ws.wscompile.plugin.at_generated
+com.sun.tools.internal.ws.wsdl.document
+com.sun.tools.internal.ws.wsdl.document.http
+com.sun.tools.internal.ws.wsdl.document.jaxws
+com.sun.tools.internal.ws.wsdl.document.mime
+com.sun.tools.internal.ws.wsdl.document.schema
+com.sun.tools.internal.ws.wsdl.document.soap
+com.sun.tools.internal.ws.wsdl.framework
+com.sun.tools.internal.ws.wsdl.parser
+com.sun.tools.internal.xjc
+com.sun.tools.internal.xjc.addon.accessors
+com.sun.tools.internal.xjc.addon.at_generated
+com.sun.tools.internal.xjc.addon.code_injector
+com.sun.tools.internal.xjc.addon.episode
+com.sun.tools.internal.xjc.addon.locator
+com.sun.tools.internal.xjc.addon.sync
+com.sun.tools.internal.xjc.api
+com.sun.tools.internal.xjc.api.impl.s2j
+com.sun.tools.internal.xjc.api.util
+com.sun.tools.internal.xjc.generator.annotation.spec
+com.sun.tools.internal.xjc.generator.bean
+com.sun.tools.internal.xjc.generator.bean.field
+com.sun.tools.internal.xjc.generator.util
+com.sun.tools.internal.xjc.model
+com.sun.tools.internal.xjc.model.nav
+com.sun.tools.internal.xjc.outline
+com.sun.tools.internal.xjc.reader
+com.sun.tools.internal.xjc.reader.dtd
+com.sun.tools.internal.xjc.reader.dtd.bindinfo
+com.sun.tools.internal.xjc.reader.gbind
+com.sun.tools.internal.xjc.reader.internalizer
+com.sun.tools.internal.xjc.reader.relaxng
+com.sun.tools.internal.xjc.reader.xmlschema
+com.sun.tools.internal.xjc.reader.xmlschema.bindinfo
+com.sun.tools.internal.xjc.reader.xmlschema.ct
+com.sun.tools.internal.xjc.reader.xmlschema.parser
+com.sun.tools.internal.xjc.runtime
+com.sun.tools.internal.xjc.util
+com.sun.tools.internal.xjc.writer
+com.sun.tools.javac
+com.sun.tools.javac.api
+com.sun.tools.javac.code
+com.sun.tools.javac.comp
+com.sun.tools.javac.file
+com.sun.tools.javac.jvm
+com.sun.tools.javac.main
+com.sun.tools.javac.model
+com.sun.tools.javac.nio
+com.sun.tools.javac.parser
+com.sun.tools.javac.processing
+com.sun.tools.javac.resources
+com.sun.tools.javac.sym
+com.sun.tools.javac.tree
+com.sun.tools.javac.util
+com.sun.tools.javadoc
+com.sun.tools.javadoc.api
+com.sun.tools.javadoc.resources
+com.sun.tools.javah
+com.sun.tools.javah.resources
+com.sun.tools.javap
+com.sun.tools.javap.resources
+com.sun.tools.jconsole
+com.sun.tools.jdeps
+com.sun.tools.jdeps.resources
+com.sun.tools.jdi
+com.sun.tools.jdi.resources
+com.sun.tools.script.shell
+com.sun.tracing
+com.sun.tracing.dtrace
+com.sun.webkit
+com.sun.webkit.dom
+com.sun.webkit.event
+com.sun.webkit.graphics
+com.sun.webkit.network
+com.sun.webkit.network.about
+com.sun.webkit.network.data
+com.sun.webkit.perf
+com.sun.webkit.plugin
+com.sun.webkit.text
+com.sun.xml.internal.bind
+com.sun.xml.internal.bind.annotation
+com.sun.xml.internal.bind.api
+com.sun.xml.internal.bind.api.impl
+com.sun.xml.internal.bind.marshaller
+com.sun.xml.internal.bind.unmarshaller
+com.sun.xml.internal.bind.util
+com.sun.xml.internal.bind.v2
+com.sun.xml.internal.bind.v2.bytecode
+com.sun.xml.internal.bind.v2.model.annotation
+com.sun.xml.internal.bind.v2.model.core
+com.sun.xml.internal.bind.v2.model.impl
+com.sun.xml.internal.bind.v2.model.nav
+com.sun.xml.internal.bind.v2.model.runtime
+com.sun.xml.internal.bind.v2.model.util
+com.sun.xml.internal.bind.v2.runtime
+com.sun.xml.internal.bind.v2.runtime.output
+com.sun.xml.internal.bind.v2.runtime.property
+com.sun.xml.internal.bind.v2.runtime.reflect
+com.sun.xml.internal.bind.v2.runtime.reflect.opt
+com.sun.xml.internal.bind.v2.runtime.unmarshaller
+com.sun.xml.internal.bind.v2.schemagen
+com.sun.xml.internal.bind.v2.schemagen.episode
+com.sun.xml.internal.bind.v2.schemagen.xmlschema
+com.sun.xml.internal.bind.v2.util
+com.sun.xml.internal.dtdparser
+com.sun.xml.internal.fastinfoset
+com.sun.xml.internal.fastinfoset.algorithm
+com.sun.xml.internal.fastinfoset.alphabet
+com.sun.xml.internal.fastinfoset.dom
+com.sun.xml.internal.fastinfoset.org.apache.xerces.util
+com.sun.xml.internal.fastinfoset.sax
+com.sun.xml.internal.fastinfoset.stax
+com.sun.xml.internal.fastinfoset.stax.events
+com.sun.xml.internal.fastinfoset.stax.factory
+com.sun.xml.internal.fastinfoset.stax.util
+com.sun.xml.internal.fastinfoset.tools
+com.sun.xml.internal.fastinfoset.util
+com.sun.xml.internal.fastinfoset.vocab
+com.sun.xml.internal.messaging.saaj
+com.sun.xml.internal.messaging.saaj.client.p2p
+com.sun.xml.internal.messaging.saaj.packaging.mime
+com.sun.xml.internal.messaging.saaj.packaging.mime.internet
+com.sun.xml.internal.messaging.saaj.packaging.mime.util
+com.sun.xml.internal.messaging.saaj.soap
+com.sun.xml.internal.messaging.saaj.soap.dynamic
+com.sun.xml.internal.messaging.saaj.soap.impl
+com.sun.xml.internal.messaging.saaj.soap.name
+com.sun.xml.internal.messaging.saaj.soap.ver1_1
+com.sun.xml.internal.messaging.saaj.soap.ver1_2
+com.sun.xml.internal.messaging.saaj.util
+com.sun.xml.internal.messaging.saaj.util.transform
+com.sun.xml.internal.org.jvnet.fastinfoset
+com.sun.xml.internal.org.jvnet.fastinfoset.sax
+com.sun.xml.internal.org.jvnet.fastinfoset.sax.helpers
+com.sun.xml.internal.org.jvnet.fastinfoset.stax
+com.sun.xml.internal.org.jvnet.mimepull
+com.sun.xml.internal.org.jvnet.staxex
+com.sun.xml.internal.rngom.ast.builder
+com.sun.xml.internal.rngom.ast.om
+com.sun.xml.internal.rngom.ast.util
+com.sun.xml.internal.rngom.binary
+com.sun.xml.internal.rngom.binary.visitor
+com.sun.xml.internal.rngom.digested
+com.sun.xml.internal.rngom.dt
+com.sun.xml.internal.rngom.dt.builtin
+com.sun.xml.internal.rngom.nc
+com.sun.xml.internal.rngom.parse
+com.sun.xml.internal.rngom.parse.compact
+com.sun.xml.internal.rngom.parse.host
+com.sun.xml.internal.rngom.parse.xml
+com.sun.xml.internal.rngom.util
+com.sun.xml.internal.rngom.xml.sax
+com.sun.xml.internal.rngom.xml.util
+com.sun.xml.internal.stream
+com.sun.xml.internal.stream.buffer
+com.sun.xml.internal.stream.buffer.sax
+com.sun.xml.internal.stream.buffer.stax
+com.sun.xml.internal.stream.dtd
+com.sun.xml.internal.stream.dtd.nonvalidating
+com.sun.xml.internal.stream.events
+com.sun.xml.internal.stream.util
+com.sun.xml.internal.stream.writers
+com.sun.xml.internal.txw2
+com.sun.xml.internal.txw2.annotation
+com.sun.xml.internal.txw2.output
+com.sun.xml.internal.ws
+com.sun.xml.internal.ws.addressing
+com.sun.xml.internal.ws.addressing.model
+com.sun.xml.internal.ws.addressing.policy
+com.sun.xml.internal.ws.addressing.v200408
+com.sun.xml.internal.ws.api
+com.sun.xml.internal.ws.api.addressing
+com.sun.xml.internal.ws.api.client
+com.sun.xml.internal.ws.api.config.management
+com.sun.xml.internal.ws.api.config.management.policy
+com.sun.xml.internal.ws.api.databinding
+com.sun.xml.internal.ws.api.fastinfoset
+com.sun.xml.internal.ws.api.ha
+com.sun.xml.internal.ws.api.handler
+com.sun.xml.internal.ws.api.message
+com.sun.xml.internal.ws.api.message.saaj
+com.sun.xml.internal.ws.api.message.stream
+com.sun.xml.internal.ws.api.model
+com.sun.xml.internal.ws.api.model.soap
+com.sun.xml.internal.ws.api.model.wsdl
+com.sun.xml.internal.ws.api.model.wsdl.editable
+com.sun.xml.internal.ws.api.pipe
+com.sun.xml.internal.ws.api.pipe.helper
+com.sun.xml.internal.ws.api.policy
+com.sun.xml.internal.ws.api.policy.subject
+com.sun.xml.internal.ws.api.server
+com.sun.xml.internal.ws.api.streaming
+com.sun.xml.internal.ws.api.wsdl.parser
+com.sun.xml.internal.ws.api.wsdl.writer
+com.sun.xml.internal.ws.assembler
+com.sun.xml.internal.ws.assembler.dev
+com.sun.xml.internal.ws.assembler.jaxws
+com.sun.xml.internal.ws.binding
+com.sun.xml.internal.ws.client
+com.sun.xml.internal.ws.client.dispatch
+com.sun.xml.internal.ws.client.sei
+com.sun.xml.internal.ws.commons.xmlutil
+com.sun.xml.internal.ws.config.management.policy
+com.sun.xml.internal.ws.config.metro.dev
+com.sun.xml.internal.ws.config.metro.util
+com.sun.xml.internal.ws.db
+com.sun.xml.internal.ws.db.glassfish
+com.sun.xml.internal.ws.developer
+com.sun.xml.internal.ws.dump
+com.sun.xml.internal.ws.encoding
+com.sun.xml.internal.ws.encoding.fastinfoset
+com.sun.xml.internal.ws.encoding.policy
+com.sun.xml.internal.ws.encoding.soap
+com.sun.xml.internal.ws.encoding.soap.streaming
+com.sun.xml.internal.ws.encoding.xml
+com.sun.xml.internal.ws.fault
+com.sun.xml.internal.ws.handler
+com.sun.xml.internal.ws.message
+com.sun.xml.internal.ws.message.jaxb
+com.sun.xml.internal.ws.message.saaj
+com.sun.xml.internal.ws.message.source
+com.sun.xml.internal.ws.message.stream
+com.sun.xml.internal.ws.model
+com.sun.xml.internal.ws.model.soap
+com.sun.xml.internal.ws.model.wsdl
+com.sun.xml.internal.ws.org.objectweb.asm
+com.sun.xml.internal.ws.policy
+com.sun.xml.internal.ws.policy.jaxws
+com.sun.xml.internal.ws.policy.jaxws.spi
+com.sun.xml.internal.ws.policy.privateutil
+com.sun.xml.internal.ws.policy.sourcemodel
+com.sun.xml.internal.ws.policy.sourcemodel.attach
+com.sun.xml.internal.ws.policy.sourcemodel.wspolicy
+com.sun.xml.internal.ws.policy.spi
+com.sun.xml.internal.ws.policy.subject
+com.sun.xml.internal.ws.protocol.soap
+com.sun.xml.internal.ws.protocol.xml
+com.sun.xml.internal.ws.resources
+com.sun.xml.internal.ws.runtime.config
+com.sun.xml.internal.ws.server
+com.sun.xml.internal.ws.server.provider
+com.sun.xml.internal.ws.server.sei
+com.sun.xml.internal.ws.spi
+com.sun.xml.internal.ws.spi.db
+com.sun.xml.internal.ws.streaming
+com.sun.xml.internal.ws.transport
+com.sun.xml.internal.ws.transport.http
+com.sun.xml.internal.ws.transport.http.client
+com.sun.xml.internal.ws.transport.http.server
+com.sun.xml.internal.ws.util
+com.sun.xml.internal.ws.util.exception
+com.sun.xml.internal.ws.util.pipe
+com.sun.xml.internal.ws.util.xml
+com.sun.xml.internal.ws.wsdl
+com.sun.xml.internal.ws.wsdl.parser
+com.sun.xml.internal.ws.wsdl.writer
+com.sun.xml.internal.ws.wsdl.writer.document
+com.sun.xml.internal.ws.wsdl.writer.document.http
+com.sun.xml.internal.ws.wsdl.writer.document.soap
+com.sun.xml.internal.ws.wsdl.writer.document.soap12
+com.sun.xml.internal.ws.wsdl.writer.document.xsd
+com.sun.xml.internal.xsom
+com.sun.xml.internal.xsom.impl
+com.sun.xml.internal.xsom.impl.parser
+com.sun.xml.internal.xsom.impl.parser.state
+com.sun.xml.internal.xsom.impl.scd
+com.sun.xml.internal.xsom.impl.util
+com.sun.xml.internal.xsom.parser
+com.sun.xml.internal.xsom.util
+com.sun.xml.internal.xsom.visitor
+java.applet
+java.awt
+java.awt.color
+java.awt.datatransfer
+java.awt.dnd
+java.awt.dnd.peer
+java.awt.event
+java.awt.font
+java.awt.geom
+java.awt.im
+java.awt.im.spi
+java.awt.image
+java.awt.image.renderable
+java.awt.peer
+java.awt.print
+java.beans
+java.beans.beancontext
+java.io
+java.lang
+java.lang.annotation
+java.lang.instrument
+java.lang.invoke
+java.lang.management
+java.lang.ref
+java.lang.reflect
+java.math
+java.net
+java.nio
+java.nio.channels
+java.nio.channels.spi
+java.nio.charset
+java.nio.charset.spi
+java.nio.file
+java.nio.file.attribute
+java.nio.file.spi
+java.rmi
+java.rmi.activation
+java.rmi.dgc
+java.rmi.registry
+java.rmi.server
+java.security
+java.security.acl
+java.security.cert
+java.security.interfaces
+java.security.spec
+java.sql
+java.text
+java.text.spi
+java.time
+java.time.chrono
+java.time.format
+java.time.temporal
+java.time.zone
+java.util
+java.util.concurrent
+java.util.concurrent.atomic
+java.util.concurrent.locks
+java.util.function
+java.util.jar
+java.util.logging
+java.util.prefs
+java.util.regex
+java.util.spi
+java.util.stream
+java.util.zip
+javafx.animation
+javafx.application
+javafx.beans
+javafx.beans.binding
+javafx.beans.property
+javafx.beans.property.adapter
+javafx.beans.value
+javafx.collections
+javafx.collections.transformation
+javafx.concurrent
+javafx.css
+javafx.embed.swing
+javafx.embed.swt
+javafx.event
+javafx.fxml
+javafx.geometry
+javafx.print
+javafx.scene
+javafx.scene.canvas
+javafx.scene.chart
+javafx.scene.control
+javafx.scene.control.cell
+javafx.scene.effect
+javafx.scene.image
+javafx.scene.input
+javafx.scene.layout
+javafx.scene.media
+javafx.scene.paint
+javafx.scene.shape
+javafx.scene.text
+javafx.scene.transform
+javafx.scene.web
+javafx.stage
+javafx.util
+javafx.util.converter
+javax.accessibility
+javax.activation
+javax.activity
+javax.annotation
+javax.annotation.processing
+javax.crypto
+javax.crypto.interfaces
+javax.crypto.spec
+javax.imageio
+javax.imageio.event
+javax.imageio.metadata
+javax.imageio.plugins.bmp
+javax.imageio.plugins.jpeg
+javax.imageio.spi
+javax.imageio.stream
+javax.jws
+javax.jws.soap
+javax.lang.model
+javax.lang.model.element
+javax.lang.model.type
+javax.lang.model.util
+javax.management
+javax.management.loading
+javax.management.modelmbean
+javax.management.monitor
+javax.management.openmbean
+javax.management.relation
+javax.management.remote
+javax.management.remote.rmi
+javax.management.timer
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+javax.net
+javax.net.ssl
+javax.print
+javax.print.attribute
+javax.print.attribute.standard
+javax.print.event
+javax.rmi
+javax.rmi.CORBA
+javax.rmi.ssl
+javax.script
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.kerberos
+javax.security.auth.login
+javax.security.auth.spi
+javax.security.auth.x500
+javax.security.cert
+javax.security.sasl
+javax.smartcardio
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.sql
+javax.sql.rowset
+javax.sql.rowset.serial
+javax.sql.rowset.spi
+javax.swing
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.metal
+javax.swing.plaf.multi
+javax.swing.plaf.nimbus
+javax.swing.plaf.synth
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.tree
+javax.swing.undo
+javax.tools
+javax.transaction
+javax.transaction.xa
+javax.xml
+javax.xml.bind
+javax.xml.bind.annotation
+javax.xml.bind.annotation.adapters
+javax.xml.bind.attachment
+javax.xml.bind.helpers
+javax.xml.bind.util
+javax.xml.crypto
+javax.xml.crypto.dom
+javax.xml.crypto.dsig
+javax.xml.crypto.dsig.dom
+javax.xml.crypto.dsig.keyinfo
+javax.xml.crypto.dsig.spec
+javax.xml.datatype
+javax.xml.namespace
+javax.xml.parsers
+javax.xml.soap
+javax.xml.stream
+javax.xml.stream.events
+javax.xml.stream.util
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stax
+javax.xml.transform.stream
+javax.xml.validation
+javax.xml.ws
+javax.xml.ws.handler
+javax.xml.ws.handler.soap
+javax.xml.ws.http
+javax.xml.ws.soap
+javax.xml.ws.spi
+javax.xml.ws.spi.http
+javax.xml.ws.wsaddressing
+javax.xml.xpath
+jdk
+jdk.internal.cmm
+jdk.internal.dynalink
+jdk.internal.dynalink.beans
+jdk.internal.dynalink.linker
+jdk.internal.dynalink.support
+jdk.internal.instrumentation
+jdk.internal.org.objectweb.asm
+jdk.internal.org.objectweb.asm.commons
+jdk.internal.org.objectweb.asm.signature
+jdk.internal.org.objectweb.asm.tree
+jdk.internal.org.objectweb.asm.tree.analysis
+jdk.internal.org.objectweb.asm.util
+jdk.internal.org.xml.sax
+jdk.internal.org.xml.sax.helpers
+jdk.internal.util.xml
+jdk.internal.util.xml.impl
+jdk.jfr.events
+jdk.management.cmm
+jdk.management.resource
+jdk.management.resource.internal
+jdk.management.resource.internal.inst
+jdk.nashorn.api.scripting
+jdk.nashorn.internal
+jdk.nashorn.internal.codegen
+jdk.nashorn.internal.codegen.types
+jdk.nashorn.internal.ir
+jdk.nashorn.internal.ir.annotations
+jdk.nashorn.internal.ir.debug
+jdk.nashorn.internal.ir.visitor
+jdk.nashorn.internal.lookup
+jdk.nashorn.internal.objects
+jdk.nashorn.internal.objects.annotations
+jdk.nashorn.internal.parser
+jdk.nashorn.internal.runtime
+jdk.nashorn.internal.runtime.arrays
+jdk.nashorn.internal.runtime.events
+jdk.nashorn.internal.runtime.linker
+jdk.nashorn.internal.runtime.logging
+jdk.nashorn.internal.runtime.options
+jdk.nashorn.internal.runtime.regexp
+jdk.nashorn.internal.runtime.regexp.joni
+jdk.nashorn.internal.runtime.regexp.joni.ast
+jdk.nashorn.internal.runtime.regexp.joni.constants
+jdk.nashorn.internal.runtime.regexp.joni.encoding
+jdk.nashorn.internal.runtime.regexp.joni.exception
+jdk.nashorn.internal.scripts
+jdk.nashorn.tools
+jdk.net
+netscape.javascript
+oracle.jrockit.jfr
+oracle.jrockit.jfr.events
+oracle.jrockit.jfr.jdkevents
+oracle.jrockit.jfr.jdkevents.throwabletransform
+oracle.jrockit.jfr.openmbean
+oracle.jrockit.jfr.parser
+oracle.jrockit.jfr.settings
+oracle.jrockit.jfr.tools
+org.ietf.jgss
+org.jcp.xml.dsig.internal
+org.jcp.xml.dsig.internal.dom
+org.omg.CORBA
+org.omg.CORBA.DynAnyPackage
+org.omg.CORBA.ORBPackage
+org.omg.CORBA.TypeCodePackage
+org.omg.CORBA.portable
+org.omg.CORBA_2_3
+org.omg.CORBA_2_3.portable
+org.omg.CosNaming
+org.omg.CosNaming.NamingContextExtPackage
+org.omg.CosNaming.NamingContextPackage
+org.omg.Dynamic
+org.omg.DynamicAny
+org.omg.DynamicAny.DynAnyFactoryPackage
+org.omg.DynamicAny.DynAnyPackage
+org.omg.IOP
+org.omg.IOP.CodecFactoryPackage
+org.omg.IOP.CodecPackage
+org.omg.Messaging
+org.omg.PortableInterceptor
+org.omg.PortableInterceptor.ORBInitInfoPackage
+org.omg.PortableServer
+org.omg.PortableServer.CurrentPackage
+org.omg.PortableServer.POAManagerPackage
+org.omg.PortableServer.POAPackage
+org.omg.PortableServer.ServantLocatorPackage
+org.omg.PortableServer.portable
+org.omg.SendingContext
+org.omg.stub.java.rmi
+org.omg.stub.javax.management.remote.rmi
+org.relaxng.datatype
+org.relaxng.datatype.helpers
+org.w3c.dom
+org.w3c.dom.bootstrap
+org.w3c.dom.css
+org.w3c.dom.events
+org.w3c.dom.html
+org.w3c.dom.ls
+org.w3c.dom.ranges
+org.w3c.dom.stylesheets
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.w3c.dom.xpath
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
+sun.applet
+sun.applet.resources
+sun.audio
+sun.awt
+sun.awt.X11
+sun.awt.datatransfer
+sun.awt.dnd
+sun.awt.event
+sun.awt.geom
+sun.awt.im
+sun.awt.image
+sun.awt.image.codec
+sun.awt.motif
+sun.awt.resources
+sun.awt.shell
+sun.awt.util
+sun.awt.windows
+sun.corba
+sun.dc
+sun.dc.path
+sun.dc.pr
+sun.font
+sun.instrument
+sun.invoke
+sun.invoke.empty
+sun.invoke.util
+sun.io
+sun.java2d
+sun.java2d.cmm
+sun.java2d.cmm.kcms
+sun.java2d.cmm.lcms
+sun.java2d.d3d
+sun.java2d.jules
+sun.java2d.loops
+sun.java2d.opengl
+sun.java2d.pipe
+sun.java2d.pipe.hw
+sun.java2d.pisces
+sun.java2d.windows
+sun.java2d.x11
+sun.java2d.xr
+sun.jvmstat.monitor
+sun.jvmstat.monitor.event
+sun.jvmstat.monitor.remote
+sun.jvmstat.perfdata.monitor
+sun.jvmstat.perfdata.monitor.protocol.file
+sun.jvmstat.perfdata.monitor.protocol.local
+sun.jvmstat.perfdata.monitor.protocol.rmi
+sun.jvmstat.perfdata.monitor.v1_0
+sun.jvmstat.perfdata.monitor.v2_0
+sun.launcher
+sun.launcher.resources
+sun.lwawt
+sun.lwawt.macosx
+sun.management
+sun.management.counter
+sun.management.counter.perf
+sun.management.jdp
+sun.management.jmxremote
+sun.management.resources
+sun.management.snmp
+sun.management.snmp.jvminstr
+sun.management.snmp.jvmmib
+sun.management.snmp.util
+sun.misc
+sun.misc.resources
+sun.net
+sun.net.dns
+sun.net.ftp
+sun.net.ftp.impl
+sun.net.httpserver
+sun.net.idn
+sun.net.sdp
+sun.net.smtp
+sun.net.spi
+sun.net.spi.nameservice
+sun.net.spi.nameservice.dns
+sun.net.util
+sun.net.www
+sun.net.www.content.audio
+sun.net.www.content.image
+sun.net.www.content.text
+sun.net.www.http
+sun.net.www.protocol.file
+sun.net.www.protocol.ftp
+sun.net.www.protocol.http
+sun.net.www.protocol.http.logging
+sun.net.www.protocol.http.ntlm
+sun.net.www.protocol.http.spnego
+sun.net.www.protocol.https
+sun.net.www.protocol.jar
+sun.net.www.protocol.mailto
+sun.net.www.protocol.netdoc
+sun.nio
+sun.nio.ch
+sun.nio.ch.sctp
+sun.nio.cs
+sun.nio.cs.ext
+sun.nio.fs
+sun.print
+sun.print.resources
+sun.reflect
+sun.reflect.annotation
+sun.reflect.generics.factory
+sun.reflect.generics.parser
+sun.reflect.generics.reflectiveObjects
+sun.reflect.generics.repository
+sun.reflect.generics.scope
+sun.reflect.generics.tree
+sun.reflect.generics.visitor
+sun.reflect.misc
+sun.rmi.log
+sun.rmi.registry
+sun.rmi.rmic
+sun.rmi.rmic.iiop
+sun.rmi.rmic.newrmic
+sun.rmi.rmic.newrmic.jrmp
+sun.rmi.runtime
+sun.rmi.server
+sun.rmi.transport
+sun.rmi.transport.proxy
+sun.rmi.transport.tcp
+sun.security.acl
+sun.security.action
+sun.security.ec
+sun.security.internal.interfaces
+sun.security.internal.spec
+sun.security.jca
+sun.security.jgss
+sun.security.jgss.krb5
+sun.security.jgss.spi
+sun.security.jgss.spnego
+sun.security.jgss.wrapper
+sun.security.krb5
+sun.security.krb5.internal
+sun.security.krb5.internal.ccache
+sun.security.krb5.internal.crypto
+sun.security.krb5.internal.crypto.dk
+sun.security.krb5.internal.ktab
+sun.security.krb5.internal.rcache
+sun.security.krb5.internal.tools
+sun.security.krb5.internal.util
+sun.security.mscapi
+sun.security.pkcs
+sun.security.pkcs10
+sun.security.pkcs11
+sun.security.pkcs11.wrapper
+sun.security.pkcs12
+sun.security.provider
+sun.security.provider.certpath
+sun.security.provider.certpath.ldap
+sun.security.provider.certpath.ssl
+sun.security.rsa
+sun.security.smartcardio
+sun.security.ssl
+sun.security.ssl.krb5
+sun.security.timestamp
+sun.security.tools
+sun.security.tools.jarsigner
+sun.security.tools.keytool
+sun.security.tools.policytool
+sun.security.util
+sun.security.validator
+sun.security.x509
+sun.swing
+sun.swing.icon
+sun.swing.plaf
+sun.swing.plaf.synth
+sun.swing.plaf.windows
+sun.swing.table
+sun.swing.text
+sun.swing.text.html
+sun.text
+sun.text.bidi
+sun.text.normalizer
+sun.text.resources
+sun.text.resources.en
+sun.tools.asm
+sun.tools.attach
+sun.tools.jar
+sun.tools.jar.resources
+sun.tools.java
+sun.tools.javac
+sun.tools.jcmd
+sun.tools.jconsole
+sun.tools.jconsole.inspector
+sun.tools.jinfo
+sun.tools.jmap
+sun.tools.jps
+sun.tools.jstack
+sun.tools.jstat
+sun.tools.jstatd
+sun.tools.native2ascii
+sun.tools.native2ascii.resources
+sun.tools.serialver
+sun.tools.tree
+sun.tools.util
+sun.tracing
+sun.tracing.dtrace
+sun.usagetracker
+sun.util
+sun.util.calendar
+sun.util.cldr
+sun.util.locale
+sun.util.locale.provider
+sun.util.logging
+sun.util.logging.resources
+sun.util.resources
+sun.util.resources.en
+sun.util.spi
+sun.util.xml
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Fri Jun 16 09:20:39 2017 -0700
@@ -92,7 +92,6 @@
import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.Modules;
-
public final class LauncherHelper {
// No instantiation
@@ -492,16 +491,16 @@
if (s.length == 2) {
String mn = s[0];
String pn = s[1];
-
- ModuleLayer.boot().findModule(mn).ifPresent(m -> {
- if (m.getDescriptor().packages().contains(pn)) {
+ ModuleLayer.boot()
+ .findModule(mn)
+ .filter(m -> m.getDescriptor().packages().contains(pn))
+ .ifPresent(m -> {
if (open) {
Modules.addOpensToAllUnnamed(m, pn);
} else {
Modules.addExportsToAllUnnamed(m, pn);
}
- }
- });
+ });
}
}
}
@@ -618,7 +617,7 @@
}
} catch (LinkageError le) {
abort(null, "java.launcher.module.error3", mainClass, m.getName(),
- le.getClass().getName() + ": " + le.getLocalizedMessage());
+ le.getClass().getName() + ": " + le.getLocalizedMessage());
}
if (c == null) {
abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -719,7 +718,7 @@
mainClass.getName(), mainClass.getModule(),
e.getClass().getName(), e.getLocalizedMessage());
} else {
- abort(e,"java.launcher.cls.error7", mainClass.getName(),
+ abort(e, "java.launcher.cls.error7", mainClass.getName(),
e.getClass().getName(), e.getLocalizedMessage());
}
}
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Fri Jun 16 09:20:39 2017 -0700
@@ -59,7 +59,7 @@
\ ALL-MODULE-PATH.\n\
\ --list-modules\n\
\ list observable modules and exit\n\
-\ --d <module name>\n\
+\ -d <module name>\n\
\ --describe-module <module name>\n\
\ describe a module and exit\n\
\ --dry-run create VM and load main class but do not execute main method.\n\
@@ -166,10 +166,11 @@
\ --add-opens <module>/<package>=<target-module>(,<target-module>)*\n\
\ updates <module> to open <package> to\n\
\ <target-module>, regardless of module declaration.\n\
-\ --permit-illegal-access\n\
-\ permit illegal access to members of types in named modules\n\
-\ by code in unnamed modules. This compatibility option will\n\
-\ be removed in the next release.\n\
+\ --illegal-access=<value>\n\
+\ permit or deny access to members of types in named modules\n\
+\ by code in unnamed modules.\n\
+\ <value> is one of "deny", "permit", "warn", or "debug"\n\
+\ This option will be removed in a future release.\n\
\ --limit-modules <module name>[,<module name>...]\n\
\ limit the universe of observable modules\n\
\ --patch-module <module>=<file>({0}<file>)*\n\
--- a/jdk/src/java.base/share/native/include/jvm.h Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/native/include/jvm.h Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -456,14 +456,6 @@
JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
/*
- * Add a package to a module.
- * module: module that will contain the package
- * package: package to add to the module
- */
-JNIEXPORT void JNICALL
-JVM_AddModulePackage(JNIEnv* env, jobject module, const char* package);
-
-/*
* Reflection support functions
*/
--- a/jdk/src/java.base/share/native/libjava/Module.c Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/java.base/share/native/libjava/Module.c Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -176,23 +176,3 @@
}
}
}
-
-JNIEXPORT void JNICALL
-Java_java_lang_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
-{
- char buf[128];
- char* pkg_name;
-
- if (pkg == NULL) {
- JNU_ThrowNullPointerException(env, "package is null");
- return;
- }
-
- pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
- if (pkg_name != NULL) {
- JVM_AddModulePackage(env, m, pkg_name);
- if (pkg_name != buf) {
- free(pkg_name);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.instrument/share/classes/java/lang/instrument/package-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,326 @@
+/*
+ * 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
+ * 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.
+ */
+
+/*
+ * Copyright 2003 Wily Technology, Inc.
+ */
+
+/**
+ * Provides services that allow Java programming language agents to instrument
+ * programs running on the JVM. The mechanism for instrumentation is modification
+ * of the byte-codes of methods.
+ *
+ * <p> An agent is deployed as a JAR file. An attribute in the JAR file manifest
+ * specifies the agent class which will be loaded to start the agent. Agents can
+ * be started in several ways:
+ *
+ * <ol>
+ * <li><p> For implementations that support a command-line interface, an agent
+ * can be started by specifying an option on the command-line. </p></li>
+ *
+ * <li><p> An implementation may support a mechanism to start agents some time
+ * after the VM has started. For example, an implementation may provide a
+ * mechanism that allows a tool to <i>attach</i> to a running application, and
+ * initiate the loading of the tool's agent into the running application. </p></li>
+ *
+ * <li><p> An agent may be packaged with an application in an executable JAR
+ * file.</p></li>
+ * </ol>
+ *
+ * <p> Each of these ways to start an agent is described below.
+ *
+ *
+ * <h3>Starting an Agent from the Command-Line Interface</h3>
+ *
+ * <p> Where an implementation provides a means to start agents from the
+ * command-line interface, an agent is started by adding the following option
+ * to the command-line:
+ *
+ * <blockquote>{@code
+ * -javaagent:<jarpath>[=<options>]
+ * }</blockquote>
+ *
+ * where <i>{@code <jarpath>}</i> is the path to the agent JAR file and
+ * <i>{@code <options>}</i> is the agent options.
+ *
+ * <p> The manifest of the agent JAR file must contain the attribute {@code
+ * Premain-Class} in its main manifest. The value of this attribute is the
+ * name of the <i>agent class</i>. The agent class must implement a public
+ * static {@code premain} method similar in principle to the {@code main}
+ * application entry point. After the Java Virtual Machine (JVM) has
+ * initialized, the {@code premain} method will be called, then the real
+ * application {@code main} method. The {@code premain} method must return
+ * in order for the startup to proceed.
+ *
+ * <p> The {@code premain} method has one of two possible signatures. The
+ * JVM first attempts to invoke the following method on the agent class:
+ *
+ * <blockquote>{@code
+ * public static void premain(String agentArgs, Instrumentation inst)
+ * }</blockquote>
+ *
+ * <p> If the agent class does not implement this method then the JVM will
+ * attempt to invoke:
+ * <blockquote>{@code
+ * public static void premain(String agentArgs)
+ * }</blockquote>
+
+ * <p> The agent class may also have an {@code agentmain} method for use when
+ * the agent is started after VM startup (see below). When the agent is started
+ * using a command-line option, the {@code agentmain} method is not invoked.
+ *
+ * <p> Each agent is passed its agent options via the {@code agentArgs} parameter.
+ * The agent options are passed as a single string, any additional parsing
+ * should be performed by the agent itself.
+ *
+ * <p> If the agent cannot be started (for example, because the agent class
+ * cannot be loaded, or because the agent class does not have an appropriate
+ * {@code premain} method), the JVM will abort. If a {@code premain} method
+ * throws an uncaught exception, the JVM will abort.
+ *
+ * <p> An implementation is not required to provide a way to start agents
+ * from the command-line interface. When it does, then it supports the
+ * {@code -javaagent} option as specified above. The {@code -javaagent} option
+ * may be used multiple times on the same command-line, thus starting multiple
+ * agents. The {@code premain} methods will be called in the order that the
+ * agents are specified on the command line. More than one agent may use the
+ * same <i>{@code <jarpath>}</i>.
+ *
+ * <p> There are no modeling restrictions on what the agent {@code premain}
+ * method may do. Anything application {@code main} can do, including creating
+ * threads, is legal from {@code premain}.
+ *
+ *
+ * <h3>Starting an Agent After VM Startup</h3>
+ *
+ * <p> An implementation may provide a mechanism to start agents sometime after
+ * the the VM has started. The details as to how this is initiated are
+ * implementation specific but typically the application has already started and
+ * its {@code main} method has already been invoked. In cases where an
+ * implementation supports the starting of agents after the VM has started the
+ * following applies:
+ *
+ * <ol>
+ *
+ * <li><p> The manifest of the agent JAR must contain the attribute {@code
+ * Agent-Class} in its main manfiest. The value of this attribute is the name
+ * of the <i>agent class</i>. </p></li>
+ *
+ * <li><p> The agent class must implement a public static {@code agentmain}
+ * method. </p></li>
+ *
+ * </ol>
+ *
+ * <p> The {@code agentmain} method has one of two possible signatures. The JVM
+ * first attempts to invoke the following method on the agent class:
+ *
+ * <blockquote>{@code
+ * public static void agentmain(String agentArgs, Instrumentation inst)
+ * }</blockquote>
+ *
+ * <p> If the agent class does not implement this method then the JVM will
+ * attempt to invoke:
+ *
+ * <blockquote>{@code
+ * public static void agentmain(String agentArgs)
+ * }</blockquote>
+ *
+ * <p> The agent class may also have a {@code premain} method for use when the
+ * agent is started using a command-line option. When the agent is started after
+ * VM startup the {@code premain} method is not invoked.
+ *
+ * <p> The agent is passed its agent options via the {@code agentArgs}
+ * parameter. The agent options are passed as a single string, any additional
+ * parsing should be performed by the agent itself.
+ *
+ * <p> The {@code agentmain} method should do any necessary initialization
+ * required to start the agent. When startup is complete the method should
+ * return. If the agent cannot be started (for example, because the agent class
+ * cannot be loaded, or because the agent class does not have a conformant
+ * {@code agentmain} method), the JVM will not abort. If the {@code agentmain}
+ * method throws an uncaught exception it will be ignored (but may be logged
+ * by the JVM for troubleshooting purposes).
+ *
+ *
+ * <h3>Including an Agent in an Executable JAR file</h3>
+ *
+ * <p> The JAR File Specification defines manifest attributes for standalone
+ * applications that are packaged as <em>executable JAR files</em>. If an
+ * implementation supports a mechanism to start an application as an executable
+ * JAR then the main manifest may include the {@code Launcher-Agent-Class}
+ * attribute to specify the class name of an agent to start before the application
+ * {@code main} method is invoked. The Java virtual machine attempts to
+ * invoke the following method on the agent class:
+ *
+ * <blockquote>{@code
+ * public static void agentmain(String agentArgs, Instrumentation inst)
+ * }</blockquote>
+ *
+ * <p> If the agent class does not implement this method then the JVM will
+ * attempt to invoke:
+ *
+ * <blockquote>{@code
+ * public static void agentmain(String agentArgs)
+ * }</blockquote>
+ *
+ * <p> The value of the {@code agentArgs} parameter is always the empty string.
+ *
+ * <p> The {@code agentmain} method should do any necessary initialization
+ * required to start the agent and return. If the agent cannot be started, for
+ * example the agent class cannot be loaded, the agent class does not define a
+ * conformant {@code agentmain} method, or the {@code agentmain} method throws
+ * an uncaught exception or error, the JVM will abort.
+ *
+ *
+ * <h3> Loading agent classes and the modules/classes available to the agent
+ * class </h3>
+ *
+ * <p> Classes loaded from the agent JAR file are loaded by the
+ * {@linkplain ClassLoader#getSystemClassLoader() system class loader} and are
+ * members of the system class loader's {@linkplain ClassLoader#getUnnamedModule()
+ * unnamed module}. The system class loader typically defines the class containing
+ * the application {@code main} method too.
+ *
+ * <p> The classes visible to the agent class are the classes visible to the system
+ * class loader and minimally include:
+ *
+ * <ul>
+ *
+ * <li><p> The classes in packages exported by the modules in the {@linkplain
+ * ModuleLayer#boot() boot layer}. Whether the boot layer contains all platform
+ * modules or not will depend on the initial module or how the application was
+ * started. </p></li>
+ *
+ * <li><p> The classes that can be defined by the system class loader (typically
+ * the class path) to be members of its unnamed module. </p></li>
+ *
+ * <li><p> Any classes that the agent arranges to be defined by the bootstrap
+ * class loader to be members of its unnamed module. </p></li>
+ *
+ * </ul>
+ *
+ * <p> If agent classes need to link to classes in platform (or other) modules
+ * that are not in the boot layer then the application may need to be started in
+ * a way that ensures that these modules are in the boot layer. In the JDK
+ * implementation for example, the {@code --add-modules} command line option can
+ * be used to add modules to the set of root modules to resolve at startup. </p>
+ *
+ * <p> Supporting classes that the agent arranges to be loaded by the bootstrap
+ * class loader (by means of {@link Instrumentation#appendToBootstrapClassLoaderSearch
+ * appendToBootstrapClassLoaderSearch} or the {@code Boot-Class-Path} attribute
+ * specified below), must link only to classes defined to the bootstrap class loader.
+ * There is no guarantee that all platform classes can be defined by the boot
+ * class loader.
+ *
+ * <p> If a custom system class loader is configured (by means of the system property
+ * {@code java.system.class.loader} as specified in the {@link
+ * ClassLoader#getSystemClassLoader() getSystemClassLoader} method) then it must
+ * define the {@code appendToClassPathForInstrumentation} method as specified in
+ * {@link Instrumentation#appendToSystemClassLoaderSearch appendToSystemClassLoaderSearch}.
+ * In other words, a custom system class loader must support the mechanism to
+ * add an agent JAR file to the system class loader search.
+ *
+ * <h3>Manifest Attributes</h3>
+ *
+ * <p> The following manifest attributes are defined for an agent JAR file:
+ *
+ * <blockquote><dl>
+ *
+ * <dt>{@code Premain-Class}</dt>
+ * <dd> When an agent is specified at JVM launch time this attribute specifies
+ * the agent class. That is, the class containing the {@code premain} method.
+ * When an agent is specified at JVM launch time this attribute is required. If
+ * the attribute is not present the JVM will abort. Note: this is a class name,
+ * not a file name or path. </dd>
+ *
+ * <dt>{@code Agent-Class}</dt>
+ * <dd> If an implementation supports a mechanism to start agents sometime after
+ * the VM has started then this attribute specifies the agent class. That is,
+ * the class containing the {@code agentmain} method. This attribute is required
+ * if it is not present the agent will not be started. Note: this is a class name,
+ * not a file name or path. </dd>
+ *
+ * <dt>{@code Launcher-Agent-Class}</dt>
+ * <dd> If an implementation supports a mechanism to start an application as an
+ * executable JAR then the main manifest may include this attribute to specify
+ * the class name of an agent to start before the application {@code main}
+ * method is invoked. </dd>
+ *
+ * <dt>{@code Boot-Class-Path}</dt>
+ * <dd> A list of paths to be searched by the bootstrap class loader. Paths
+ * represent directories or libraries (commonly referred to as JAR or zip
+ * libraries on many platforms). These paths are searched by the bootstrap class
+ * loader after the platform specific mechanisms of locating a class have failed.
+ * Paths are searched in the order listed. Paths in the list are separated by one
+ * or more spaces. A path takes the syntax of the path component of a hierarchical
+ * URI. The path is absolute if it begins with a slash character ('/'), otherwise
+ * it is relative. A relative path is resolved against the absolute path of the
+ * agent JAR file. Malformed and non-existent paths are ignored. When an agent is
+ * started sometime after the VM has started then paths that do not represent a
+ * JAR file are ignored. This attribute is optional. </dd>
+ *
+ * <dt>{@code Can-Redefine-Classes}</dt>
+ * <dd> Boolean ({@code true} or {@code false}, case irrelevant). Is the ability
+ * to redefine classes needed by this agent. Values other than {@code true} are
+ * considered {@code false}. This attribute is optional, the default is {@code
+ * false}. </dd>
+ *
+ * <dt>{@code Can-Retransform-Classes}</dt>
+ * <dd> Boolean ({@code true} or {@code false}, case irrelevant). Is the ability
+ * to retransform classes needed by this agent. Values other than {@code true}
+ * are considered {@code false}. This attribute is optional, the default is
+ * {@code false}. </dd>
+ *
+ * <dt>{@code Can-Set-Native-Method-Prefix}</dt>
+ * <dd> Boolean ({@code true} or {@code false}, case irrelevant). Is the ability
+ * to set native method prefix needed by this agent. Values other than {@code
+ * true} are considered {@code false}. This attribute is optional, the default
+ * is {@code false}. </dd>
+ *
+ * </dl></blockquote>
+ *
+ * <p> An agent JAR file may have both the {@code Premain-Class} and {@code
+ * Agent-Class} attributes present in the manifest. When the agent is started
+ * on the command-line using the {@code -javaagent} option then the {@code
+ * Premain-Class} attribute specifies the name of the agent class and the {@code
+ * Agent-Class} attribute is ignored. Similarly, if the agent is started sometime
+ * after the VM has started, then the {@code Agent-Class} attribute specifies
+ * the name of the agent class (the value of {@code Premain-Class} attribute is
+ * ignored).
+ *
+ *
+ * <h3>Instrumenting code in modules</h3>
+ *
+ * <p> As an aid to agents that deploy supporting classes on the search path of
+ * the bootstrap class loader, or the search path of the class loader that loads
+ * the main agent class, the Java virtual machine arranges for the module of
+ * transformed classes to read the unnamed module of both class loaders.
+ *
+ * @since 1.5
+ * @revised 1.6
+ * @revised 9
+ */
+
+package java.lang.instrument;
\ No newline at end of file
--- a/jdk/src/java.instrument/share/classes/java/lang/instrument/package.html Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-<!--
- 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
- 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.
--->
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
- Copyright 2003 Wily Technology, Inc.
-
--->
-</head>
-
-<body bgcolor="white">
-
-Provides services that allow Java programming language agents to instrument programs running on the JVM.
-The mechanism for instrumentation is modification of the byte-codes of methods.
-
-<h2>Package Specification</h2>
-
-<P>
-An agent is deployed as a JAR file. An attribute in the JAR file manifest specifies the
-agent class which will be loaded to start the agent. For implementations that support a command-line
-interface, an agent is started by specifying an option on the command-line.
-Implementations may also support a mechanism to start agents some time after the VM has
-started. For example, an implementation may provide a mechanism that allows a tool to
-<i>attach</i> to a running application, and initiate the loading of the tool's agent into
-the running application. The details as to how the load is initiated, is implementation
-dependent.
-
-<h3>Command-Line Interface</h3>
-
-<P>
-An implementation is not required to provide a way to start agents from the
-command-line interface. On implementations that do provide a way to start agents
-from the command-line interface, an agent is started by adding this option to
-the command-line:
-<blockquote>
-<code><b>-javaagent:</b></code><i>jarpath[</i><code><b>=</b></code><i>options]</i>
-</blockquote>
-<i>jarpath</i> is the path to the agent JAR file.
-<i>options</i> is the agent options.
-This switch may be used multiple times on the same command-line,
-thus creating multiple agents.
-More than one agent may use the same <i>jarpath</i>.
-An agent JAR file must conform to the JAR file specification.
-
-<P>
-The manifest of the agent JAR file must contain the attribute <code>Premain-Class</code>. The
-value of this attribute is the name of the <i>agent class</i>. The agent class must implement a
-public static <code>premain</code> method similar in principle to the <code>main</code> application
-entry point. After the Java Virtual Machine (JVM) has initialized, each <code>premain</code> method
-will be called in the order the agents were specified, then the real application
-<code>main</code> method will be called.
-Each <code>premain</code> method must return in order for the startup sequence to proceed.
-
-<P>
-The <code>premain</code> method has one of two possible signatures. The JVM first attempts to
-invoke the following method on the agent class:
-
-<blockquote>
-<code>public static void
-premain(String agentArgs, Instrumentation inst);
-</code>
-</blockquote>
-
-<P>
-If the agent class does not implement this method then the JVM will attempt to invoke:
-
-<blockquote>
-<code>public static void
-premain(String agentArgs);
-</code>
-</blockquote>
-
-<P>
-The agent class may also have an <code>agentmain</code> method for use when the agent is started
-after VM startup. When the agent is started using a command-line option, the <code>agentmain</code>
-method is not invoked.
-
-
-<P>
-The agent class will be loaded by the system class loader
-(see {@link java.lang.ClassLoader#getSystemClassLoader ClassLoader.getSystemClassLoader}). This is
-the class loader which typically loads the class containing the application <code>main</code> method.
-The system class loader must support a mechanism to add an agent JAR file to the system class path.
-If it is a custom system class loader then it must define the
-<code>appendToClassPathForInstrumentation</code> method as specified in
-{@link Instrumentation#appendToSystemClassLoaderSearch appendToSystemClassLoaderSearch}.
-The <code>premain</code> methods will be run under the same security and classloader
-rules as the application <code>main</code> method.
-There are no modeling restrictions on what the agent <code>premain</code> method may do.
-Anything application <code>main</code> can do, including creating threads, is legal from
-<code>premain</code>.
-
-
-<P>
-Each agent is passed its agent options via the <code>agentArgs</code> parameter.
-The agent options are passed as a single string,
-any additional parsing should be performed by the agent itself.
-
-<P>
-If the agent cannot be resolved
-(for example, because the agent class cannot be loaded,
-or because the agent class does not have an appropriate <code>premain</code> method), the JVM will abort.
-If a <code>premain</code> method throws an uncaught exception, the JVM will abort.
-
-
-<h3>Starting Agents After VM Startup</h3>
-
-<p>
-An implementation may provide a mechanism to start agents sometime after the
-the VM has started. The details as to how this is initiated are implementation
-specific but typically the application has already started and its <code>
-main</code> method has already been invoked. In cases where an implementation
-supports the starting of agents after the VM has started the following applies:
-
-<ol>
- <li><p>The manifest of the agent JAR must contain the attribute <code>Agent-Class</code>.
- The value of this attribute is the name of the <i>agent class</i>. </p></li>
-
- <li><p>The agent class must implement a public static <code>agentmain</code> method. </p></li>
-
- <li><p>The system class loader (
- {@link java.lang.ClassLoader#getSystemClassLoader ClassLoader.getSystemClassLoader}) must
- support a mechanism to add an agent JAR file to the system class path.
- If it is a custom system class loader then it must define the
- <code>appendToClassPathForInstrumentation</code> method as specified in
- {@link Instrumentation#appendToSystemClassLoaderSearch appendToSystemClassLoaderSearch}.</li>
-</ol>
-
-<P>
-The agent JAR is appended to the system class path. This is the class loader that typically loads
-the class containing the application <code>main</code> method. The agent class is loaded and the
-JVM attempts to invoke the <code>agentmain</code> method. The JVM first attempts to invoke
-the following method on the agent class:
-
-<blockquote>
-<code>public static void
-agentmain(String agentArgs, Instrumentation inst);
-</code>
-</blockquote>
-
-<P>
-If the agent class does not implement this method then the JVM will attempt to invoke:
-
-<blockquote>
-<code>public static void
-agentmain(String agentArgs);
-</code>
-</blockquote>
-
-<P>
-The agent class may also have an <code>premain</code> method for use when the agent is started
-using a command-line option. When the agent is started after VM startup the <code>premain</code>
-method is not invoked.
-
-
-<P>
-The agent is passed its agent options via the <code>agentArgs</code> parameter.
-The agent options are passed as a single string,
-any additional parsing should be performed by the agent itself.
-
-<P>
-The <code>agentmain</code> method should do any necessary initialization
-required to start the agent. When startup is complete the method should
-return. If the agent cannot be started
-(for example, because the agent class cannot be loaded,
-or because the agent class does not have a conformant <code>agentmain</code> method), the JVM will
-not abort. If the <code>agentmain</code> method throws an uncaught exception it will be ignored.
-
-
-<h3>Deploying Agents in Executable JAR file</h3>
-
-The JAR File Specification defines manifest attributes for standalone applications that are
-bundled as <em>executable JAR files</em>. If an implementation supports a mechanism to start
-an application as an executable JAR then the main manifest may include the
-<code>Launcher-Agent-Class</code> attribute to specify the class name
-of an agent to start before the application <code>main</code> method is invoked. The Java
-virtual machine attempts to invoke the following method on the agent class:
-
-<blockquote>
- <code>public static void
- agentmain(String agentArgs, Instrumentation inst);
- </code>
-</blockquote>
-
-<P>
-If the agent class does not implement this method then the JVM will attempt to invoke:
-
-<blockquote>
- <code>public static void
- agentmain(String agentArgs);
- </code>
-</blockquote>
-
-<p>
-The value of the <code>agentArgs</code> parameter is always the empty string.
-
-<P>
-The <code>agentmain</code> method should do any necessary initialization
-required to start the agent and return. If the agent cannot be started, for
-example the agent class cannot be loaded, the agent class does not define a
-conformant <code>agentmain</code> method, or the <code>agentmain</code> method
-throws an uncaught exception or error, the JVM will abort.
-
-
-<h3>Visibility</h3>
-
-The types visible to the agent class are the types visible to the system class
-loader. They minimally include the types in packages exported by
-<a href="{@docRoot}/java.base-summary.html">java.base</a> and
-<a href="{@docRoot}/java.instrument-summary.html">java.instrument</a>.
-Whether all {@linkplain ClassLoader#getPlatformClassLoader() platform classes}
-are visible or not will depend on the initial module or application.
-
-<p>
-Supporting classes that the agent makes visible to the bootstrap class loader
-(by means of {@link Instrumentation#appendToBootstrapClassLoaderSearch
-appendToBootstrapClassLoaderSearch} or the <code>Boot-Class-Path</code> attribute
-specified below) can only link to types defined to the bootstrap class loader.
-There is no guarantee that all platform classes are visible to the boot class
-loader.
-
-
-<h3>Manifest Attributes</h3>
-
-The following manifest attributes are defined for an agent JAR file:
-<blockquote>
-<dl>
-<dt><code>Premain-Class</code></dt>
-<dd>
- When an agent is specified at JVM launch time this attribute
- specifies the agent class.
- That is, the class containing the <code>premain</code> method.
- When an agent is specified at JVM launch time this attribute
- is required. If the attribute is not present the JVM will abort.
- Note: this is a class name, not a file name or path.
-</dd>
-<dt><code>Agent-Class</code></dt>
-<dd>
- If an implementation supports a mechanism to start agents
- sometime after the VM has started then this attribute specifies
- the agent class.
- That is, the class containing the <code>agentmain</code> method.
- This attribute is required, if it is not present the agent
- will not be started.
- Note: this is a class name, not a file name or path.
-</dd>
-<dt><code>Launcher-Agent-Class</code></dt>
-<dd>
- If an implementation supports a mechanism to start an application
- as an executable JAR then the main manifest may include this
- attribute to specify the class name of an agent to start before the
- application <code>main</code> method is invoked.
-</dd>
-<dt><code>Boot-Class-Path</code></dt>
-<dd>
- A list of paths to be searched by the bootstrap class
- loader. Paths represent directories or libraries
- (commonly referred to as JAR or zip libraries on
- many platforms).
- These paths are searched by the
- bootstrap class loader after the platform specific
- mechanisms of locating a class have failed.
- Paths are searched in the order listed.
- Paths in the list are separated by one or more spaces.
- A path takes the syntax of the path component of a
- hierarchical URI. The path is
- absolute if it begins with a slash character ('/'),
- otherwise it is relative. A relative path is resolved
- against the absolute path of the agent JAR file.
- Malformed and non-existent paths are ignored.
- When an agent is started sometime after the VM has
- started then paths that do not represent a JAR file
- are ignored.
- This attribute is optional.
-</dd>
-<dt><code>Can-Redefine-Classes</code></dt>
-<dd>
- Boolean (<code>true</code> or <code>false</code>, case irrelevant).
- Is the ability to redefine classes
- needed by this agent.
- Values other than <code>true</code> are considered <code>false</code>.
- This attribute is optional, the default is <code>false</code>.
-</dd>
-<dt><code>Can-Retransform-Classes</code></dt>
-<dd>
- Boolean (<code>true</code> or <code>false</code>, case irrelevant).
- Is the ability to retransform classes
- needed by this agent.
- Values other than <code>true</code> are considered <code>false</code>.
- This attribute is optional, the default is <code>false</code>.
-</dd>
-<dt><code>Can-Set-Native-Method-Prefix</code></dt>
-<dd>
- Boolean (<code>true</code> or <code>false</code>, case irrelevant).
- Is the ability to set native method prefix needed by this agent.
- Values other than <code>true</code> are considered <code>false</code>.
- This attribute is optional, the default is <code>false</code>.
-</dd>
-</dl>
-</blockquote>
-
-<p>
-An agent JAR file may have both the <code>Premain-Class</code> and <code>Agent-Class</code>
-attributes present in the manifest. When the agent is started on the command-line using
-the <code>-javaagent</code> option then the <code>Premain-Class</code> attribute
-specifies the name of the agent class and the <code>Agent-Class</code> attribute is
-ignored. Similarly, if the agent is started sometime after the VM has started, then
-the <code>Agent-Class</code> attribute specifies the name of the agent class
-(the value of <code>Premain-Class</code> attribute is ignored).
-
-
-<h3>Instrumenting code in modules</h3>
-
-As an aid to agents that deploy supporting classes on the search path of the
-bootstrap class loader, or the search path of the class loader that loads
-the main agent class, the Java virtual machine arranges for the module of
-transformed classes to read the unnamed module of both class loaders.
-
-
-<h2>Related Documentation</h2>
-
-For tool documentation, please see:
-<ul>
- <li><a href="{@docRoot}/../technotes/tools/index.html">JDK Tools and Utilities</a>
-</ul>
-
-@since 1.5
-@revised 1.6
-
-</body>
-</html>
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Fri Jun 16 09:20:39 2017 -0700
@@ -34,6 +34,10 @@
import java.lang.module.ModuleDescriptor.Provides;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleDescriptor.Version;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
@@ -41,13 +45,17 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.IntSupplier;
+import java.util.stream.Collectors;
import jdk.internal.module.Checks;
import jdk.internal.module.ClassFileAttributes;
import jdk.internal.module.ClassFileConstants;
+import jdk.internal.module.IllegalAccessMaps;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleInfo.Attributes;
import jdk.internal.module.ModuleInfoExtender;
@@ -601,6 +609,10 @@
// generate SystemModules::moduleResolutions
genModuleResolutionsMethod();
+ // generate SystemModules::concealedPackagesToOpen and
+ // SystemModules::exportedPackagesToOpen
+ genXXXPackagesToOpenMethods();
+
return cw;
}
@@ -733,6 +745,96 @@
mresmv.visitEnd();
}
+ /**
+ * Generate SystemModules::concealedPackagesToOpen and
+ * SystemModules::exportedPackagesToOpen methods.
+ */
+ private void genXXXPackagesToOpenMethods() {
+ List<ModuleDescriptor> descriptors = moduleInfos.stream()
+ .map(ModuleInfo::descriptor)
+ .collect(Collectors.toList());
+ ModuleFinder finder = finderOf(descriptors);
+ IllegalAccessMaps maps = IllegalAccessMaps.generate(finder);
+ generate("concealedPackagesToOpen", maps.concealedPackagesToOpen());
+ generate("exportedPackagesToOpen", maps.exportedPackagesToOpen());
+ }
+
+ /**
+ * Generate SystemModules:XXXPackagesToOpen
+ */
+ private void generate(String methodName, Map<String, Set<String>> map) {
+ // Map<String, Set<String>> XXXPackagesToOpen()
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC+ACC_STATIC,
+ methodName,
+ "()Ljava/util/Map;",
+ "()Ljava/util/Map;",
+ null);
+ mv.visitCode();
+
+ // new Map$Entry[moduleCount]
+ pushInt(mv, map.size());
+ mv.visitTypeInsn(ANEWARRAY, "java/util/Map$Entry");
+
+ int index = 0;
+ for (Map.Entry<String, Set<String>> e : map.entrySet()) {
+ String moduleName = e.getKey();
+ Set<String> packages = e.getValue();
+ int packageCount = packages.size();
+
+ mv.visitInsn(DUP);
+ pushInt(mv, index);
+ mv.visitLdcInsn(moduleName);
+
+ // use Set.of(Object[]) when there are more than 2 packages
+ // use Set.of(Object) or Set.of(Object, Object) when fewer packages
+ if (packageCount > 2) {
+ pushInt(mv, packageCount);
+ mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
+ int i = 0;
+ for (String pn : packages) {
+ mv.visitInsn(DUP);
+ pushInt(mv, i);
+ mv.visitLdcInsn(pn);
+ mv.visitInsn(AASTORE);
+ i++;
+ }
+ mv.visitMethodInsn(INVOKESTATIC,
+ "java/util/Set",
+ "of",
+ "([Ljava/lang/Object;)Ljava/util/Set;",
+ true);
+ } else {
+ StringBuilder sb = new StringBuilder("(");
+ for (String pn : packages) {
+ mv.visitLdcInsn(pn);
+ sb.append("Ljava/lang/Object;");
+ }
+ sb.append(")Ljava/util/Set;");
+ mv.visitMethodInsn(INVOKESTATIC,
+ "java/util/Set",
+ "of",
+ sb.toString(),
+ true);
+ }
+
+ String desc = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map$Entry;";
+ mv.visitMethodInsn(INVOKESTATIC,
+ "java/util/Map",
+ "entry",
+ desc,
+ true);
+ mv.visitInsn(AASTORE);
+ index++;
+ }
+
+ // invoke Map.ofEntries(Map$Entry[])
+ mv.visitMethodInsn(INVOKESTATIC, "java/util/Map", "ofEntries",
+ "([Ljava/util/Map$Entry;)Ljava/util/Map;", true);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
public boolean isOverriddenClass(String path) {
return path.equals("/java.base/" + CLASSNAME + ".class");
}
@@ -1461,4 +1563,31 @@
}
}
}
+
+ static ModuleFinder finderOf(Iterable<ModuleDescriptor> descriptors) {
+ Map<String, ModuleReference> namesToReference = new HashMap<>();
+ for (ModuleDescriptor descriptor : descriptors) {
+ String name = descriptor.name();
+ URI uri = URI.create("module:/" + name);
+ ModuleReference mref = new ModuleReference(descriptor, uri) {
+ @Override
+ public ModuleReader open() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ namesToReference.putIfAbsent(name, mref);
+ }
+
+ return new ModuleFinder() {
+ @Override
+ public Optional<ModuleReference> find(String name) {
+ Objects.requireNonNull(name);
+ return Optional.ofNullable(namesToReference.get(name));
+ }
+ @Override
+ public Set<ModuleReference> findAll() {
+ return new HashSet<>(namesToReference.values());
+ }
+ };
+ }
}
--- a/jdk/test/ProblemList.txt Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/ProblemList.txt Fri Jun 16 09:20:39 2017 -0700
@@ -295,6 +295,8 @@
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java 8057732 generic-all
+com/sun/tools/attach/StartManagementAgent.java 8179700 generic-all
+
############################################################################
# jdk_other
--- a/jdk/test/java/lang/ModuleLayer/BasicLayerTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleLayer/BasicLayerTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -1054,8 +1054,6 @@
/**
* Attempt to create a layer with a module containing a "java" package.
- * This should only be allowed when the module is defined to the platform
- * class loader.
*/
@Test(dataProvider = "javaPackages")
public void testLayerWithJavaPackage(String mn, String pn) {
@@ -1067,7 +1065,6 @@
.resolve(finder, ModuleFinder.of(), Set.of(mn));
assertTrue(cf.modules().size() == 1);
- ClassLoader pcl = ClassLoader.getPlatformClassLoader();
ClassLoader scl = ClassLoader.getSystemClassLoader();
try {
@@ -1084,15 +1081,6 @@
ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
assertTrue(false);
} catch (LayerInstantiationException e) { }
-
- // create layer with module defined to platform class loader
- ModuleLayer layer = ModuleLayer.boot().defineModules(cf, _mn -> pcl);
- Optional<Module> om = layer.findModule(mn);
- assertTrue(om.isPresent());
- Module foo = om.get();
- assertTrue(foo.getClassLoader() == pcl);
- assertTrue(foo.getPackages().size() == 1);
- assertTrue(foo.getPackages().iterator().next().equals(pn));
}
@@ -1101,8 +1089,7 @@
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testLayerWithBootLoader() {
- ModuleDescriptor descriptor = newBuilder("m1")
- .build();
+ ModuleDescriptor descriptor = newBuilder("m1").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
@@ -1116,6 +1103,25 @@
/**
+ * Attempt to create a layer with a module defined to the platform loader
+ */
+ @Test(expectedExceptions = { LayerInstantiationException.class })
+ public void testLayerWithPlatformLoader() {
+ ModuleDescriptor descriptor = newBuilder("m1").build();
+
+ ModuleFinder finder = ModuleUtils.finderOf(descriptor);
+
+ Configuration cf = ModuleLayer.boot()
+ .configuration()
+ .resolve(finder, ModuleFinder.of(), Set.of("m1"));
+ assertTrue(cf.modules().size() == 1);
+
+ ClassLoader cl = ClassLoader.getPlatformClassLoader();
+ ModuleLayer.boot().defineModules(cf, mn -> cl );
+ }
+
+
+ /**
* Parent of configuration != configuration of parent layer
*/
@Test(expectedExceptions = { IllegalArgumentException.class })
--- a/jdk/test/java/lang/ModuleLayer/LayerAndLoadersTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleLayer/LayerAndLoadersTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -32,17 +32,21 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
+import java.lang.module.ResolvedModule;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
@@ -63,7 +67,6 @@
@BeforeTest
public void setup() throws Exception {
-
// javac -d mods --module-source-path src src/**
assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,
"--module-source-path", SRC_DIR.toString()));
@@ -77,7 +80,6 @@
* m1 requires m2 and m3
*/
public void testWithOneLoader() throws Exception {
-
Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -95,7 +97,6 @@
assertTrue(cl3 == cl1);
invoke(layer, "m1", "p.Main");
-
}
@@ -106,7 +107,6 @@
* m1 requires m2 and m3
*/
public void testWithManyLoaders() throws Exception {
-
Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -127,7 +127,6 @@
assertTrue(cl3 != cl2);
invoke(layer, "m1", "p.Main");
-
}
@@ -141,7 +140,6 @@
* m4 provides S with ...
*/
public void testServicesWithOneLoader() throws Exception {
-
Configuration cf = resolveAndBind("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -168,7 +166,6 @@
assertTrue(serviceType.isInstance(provider));
assertTrue(provider.getClass().getClassLoader() == cl1);
assertFalse(iter.hasNext());
-
}
@@ -182,7 +179,6 @@
* m4 provides S with ...
*/
public void testServicesWithManyLoaders() throws Exception {
-
Configuration cf = resolveAndBind("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -220,7 +216,6 @@
assertTrue(provider.getClass().getClassLoader() == cl4);
assertFalse(iter.hasNext());
}
-
}
@@ -229,7 +224,6 @@
* to the given parent class loader.
*/
public void testDelegationToParent() throws Exception {
-
Configuration cf = resolve("m1");
ClassLoader parent = this.getClass().getClassLoader();
@@ -250,7 +244,6 @@
// many loader with boot loader as parent
layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);
testLoadFail(layer, cn);
-
}
@@ -262,7 +255,6 @@
* m2 exports p
*/
public void testOverlappingPackages() {
-
ModuleDescriptor descriptor1
= ModuleDescriptor.newModule("m1").exports("p").build();
@@ -284,7 +276,6 @@
// should be okay to have one module per class loader
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, null);
checkLayer(layer, "m1", "m2");
-
}
@@ -296,7 +287,6 @@
* layer2: m3 reads m1, m4 reads m2
*/
public void testSplitDelegation() {
-
ModuleDescriptor descriptor1
= ModuleDescriptor.newModule("m1").exports("p").build();
@@ -332,7 +322,6 @@
// no split delegation when modules have their own class loader
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
checkLayer(layer2, "m3", "m4");
-
}
@@ -345,7 +334,6 @@
* layer2: m1, m2, m4 => same loader
*/
public void testOverriding1() throws Exception {
-
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
@@ -381,7 +369,6 @@
assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);
assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);
-
}
@@ -394,7 +381,6 @@
* layer2: m1, m2, m3 => loader pool
*/
public void testOverriding2() throws Exception {
-
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
@@ -476,7 +462,6 @@
loader6.loadClass("q.Hello");
assertTrue(false);
} catch (ClassNotFoundException expected) { }
-
}
@@ -488,7 +473,6 @@
* layer2: m1, m3 => same loader
*/
public void testOverriding3() throws Exception {
-
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithOneLoader(cf1, null);
@@ -513,7 +497,6 @@
assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);
assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);
assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);
-
}
@@ -525,7 +508,6 @@
* layer2: m1, m3 => loader pool
*/
public void testOverriding4() throws Exception {
-
Configuration cf1 = resolve("m1");
ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, null);
@@ -565,49 +547,133 @@
assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6);
assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
-
}
/**
- * Basic test of resource loading with a class loader created by
- * Layer.defineModulesWithOneLoader.
+ * Basic test for locating resources with a class loader created by
+ * defineModulesWithOneLoader.
*/
- public void testResourcesOneLoader() throws Exception {
+ public void testResourcesWithOneLoader() throws Exception {
Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
+
ClassLoader loader = layer.findLoader("m1");
- testResourceLoading(loader, "p/Main.class");
+ assertNotNull(loader);
+
+ // check that getResource and getResources are consistent
+ URL url1 = loader.getResource("module-info.class");
+ URL url2 = loader.getResources("module-info.class").nextElement();
+ assertEquals(url1.toURI(), url2.toURI());
+
+ // use getResources to find module-info.class resources
+ Enumeration<URL> urls = loader.getResources("module-info.class");
+ List<String> list = readModuleNames(urls);
+
+ // m1, m2, ... should be first (order not specified)
+ int count = cf.modules().size();
+ cf.modules().stream()
+ .map(ResolvedModule::name)
+ .forEach(mn -> assertTrue(list.indexOf(mn) < count));
+
+ // java.base should be after m1, m2, ...
+ assertTrue(list.indexOf("java.base") >= count);
+
+ // check resources(String)
+ List<String> list2 = loader.resources("module-info.class")
+ .map(this::readModuleName)
+ .collect(Collectors.toList());
+ assertEquals(list2, list);
+
+ // check nulls
+ try {
+ loader.getResource(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
+ try {
+ loader.getResources(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
+ try {
+ loader.resources(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
}
/**
- * Basic test of resource loading with a class loader created by
- * Layer.defineModulesWithOneLoader.
+ * Basic test for locating resources with class loaders created by
+ * defineModulesWithManyLoaders.
*/
- public void testResourcesManyLoaders() throws Exception {
+ public void testResourcesWithManyLoaders() throws Exception {
Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
- ClassLoader loader = layer.findLoader("m1");
- testResourceLoading(loader, "p/Main.class");
+
+ for (Module m : layer.modules()) {
+ String name = m.getName();
+ ClassLoader loader = m.getClassLoader();
+ assertNotNull(loader);
+
+ // getResource should find the module-info.class for the module
+ URL url = loader.getResource("module-info.class");
+ assertEquals(readModuleName(url), name);
+
+ // list of modules names read from module-info.class
+ Enumeration<URL> urls = loader.getResources("module-info.class");
+ List<String> list = readModuleNames(urls);
+
+ // module should be the first element
+ assertTrue(list.indexOf(name) == 0);
+
+ // the module-info.class for the other modules in the layer
+ // should not be found
+ layer.modules().stream()
+ .map(Module::getName)
+ .filter(mn -> !mn.equals(name))
+ .forEach(mn -> assertTrue(list.indexOf(mn) < 0));
+
+ // java.base cannot be the first element
+ assertTrue(list.indexOf("java.base") > 0);
+
+ // check resources(String)
+ List<String> list2 = loader.resources("module-info.class")
+ .map(this::readModuleName)
+ .collect(Collectors.toList());
+ assertEquals(list2, list);
+
+ // check nulls
+ try {
+ loader.getResource(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
+ try {
+ loader.getResources(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
+ try {
+ loader.resources(null);
+ assertTrue(false);
+ } catch (NullPointerException e) { }
+ }
}
- /**
- * Test that a resource is located by a class loader.
- */
- private void testResourceLoading(ClassLoader loader, String name)
- throws IOException
- {
- URL url = loader.getResource(name);
- assertNotNull(url);
+ private List<String> readModuleNames(Enumeration<URL> e) {
+ List<String> list = new ArrayList<>();
+ while (e.hasMoreElements()) {
+ URL url = e.nextElement();
+ list.add(readModuleName(url));
+ }
+ return list;
+ }
- try (InputStream in = loader.getResourceAsStream(name)) {
- assertNotNull(in);
+ private String readModuleName(URL url) {
+ try (InputStream in = url.openStream()) {
+ ModuleDescriptor descriptor = ModuleDescriptor.read(in);
+ return descriptor.name();
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
}
-
- Enumeration<URL> urls = loader.getResources(name);
- assertTrue(urls.hasMoreElements());
}
--- a/jdk/test/java/lang/ModuleLayer/LayerControllerTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleLayer/LayerControllerTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -59,11 +59,17 @@
.packages(Set.of("p2"))
.build();
- ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
+ ModuleDescriptor descriptor3
+ = ModuleDescriptor.newModule("m3")
+ .requires("java.base")
+ .packages(Set.of("p3"))
+ .build();
+
+ ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration cf = bootLayer.configuration()
- .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+ .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2", "m3"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -72,9 +78,10 @@
ModuleLayer layer = controller.layer();
- assertTrue(layer.modules().size() == 2);
+ assertTrue(layer.modules().size() == 3);
assertTrue(layer.findModule("m1").isPresent());
assertTrue(layer.findModule("m2").isPresent());
+ assertTrue(layer.findModule("m3").isPresent());
return controller;
}
@@ -88,18 +95,34 @@
ModuleLayer layer = controller.layer();
Module m1 = layer.findModule("m1").orElseThrow(RuntimeException::new);
Module m2 = layer.findModule("m2").orElseThrow(RuntimeException::new);
+ Module m3 = layer.findModule("m3").orElseThrow(RuntimeException::new);
assertFalse(m1.canRead(m2));
+ assertFalse(m1.canRead(m3));
assertFalse(m1.isExported("p1"));
assertFalse(m1.isOpen("p1"));
assertFalse(m1.isExported("p1", m2));
+ assertFalse(m1.isExported("p1", m3));
assertFalse(m1.isOpen("p1", m2));
+ assertFalse(m1.isOpen("p1", m3));
assertFalse(m2.canRead(m1));
+ assertFalse(m2.canRead(m3));
assertFalse(m2.isExported("p2"));
assertFalse(m2.isOpen("p2"));
assertFalse(m2.isExported("p2", m1));
+ assertFalse(m2.isExported("p2", m3));
assertFalse(m2.isOpen("p2", m1));
+ assertFalse(m2.isOpen("p2", m3));
+
+ assertFalse(m3.canRead(m1));
+ assertFalse(m3.canRead(m2));
+ assertFalse(m3.isExported("p3"));
+ assertFalse(m3.isOpen("p3"));
+ assertFalse(m3.isExported("p3", m1));
+ assertFalse(m3.isExported("p3", m2));
+ assertFalse(m3.isOpen("p3", m1));
+ assertFalse(m3.isOpen("p3", m2));
// update m1 to read m2
assertTrue(controller.addReads(m1, m2) == controller);
@@ -111,19 +134,33 @@
assertTrue(m1.canRead(m2));
assertTrue(m1.canRead(m1));
- // update m1 to open p1 to m2
- assertTrue(controller.addOpens(m1, "p1", m2) == controller);
+ // update m1 to export p1 to m2
+ assertTrue(controller.addExports(m1, "p1", m2) == controller);
assertTrue(m1.isExported("p1", m2));
- assertTrue(m1.isOpen("p1", m2));
+ assertFalse(m1.isOpen("p1", m2));
assertFalse(m1.isExported("p1"));
assertFalse(m1.isOpen("p1"));
- // update m2 to open p2 to m1
- assertTrue(controller.addOpens(m2, "p2", m1) == controller);
- assertTrue(m2.isExported("p2", m1));
- assertTrue(m2.isOpen("p2", m1));
- assertFalse(m2.isExported("p2"));
- assertFalse(m2.isOpen("p2"));
+ // update m3 to open p3 to m1
+ assertTrue(controller.addExports(m3, "p3", m1) == controller);
+ assertTrue(m3.isExported("p3", m1));
+ assertFalse(m3.isOpen("p3", m1));
+ assertFalse(m3.isExported("p3"));
+ assertFalse(m3.isOpen("p3"));
+
+ // update m1 to open p1 to m3
+ assertTrue(controller.addOpens(m1, "p1", m3) == controller);
+ assertTrue(m1.isExported("p1", m3));
+ assertTrue(m1.isOpen("p1", m3));
+ assertFalse(m1.isExported("p1"));
+ assertFalse(m1.isOpen("p1"));
+
+ // update m3 to open p3 to m1
+ assertTrue(controller.addOpens(m3, "p3", m1) == controller);
+ assertTrue(m3.isExported("p3", m1));
+ assertTrue(m3.isOpen("p3", m1));
+ assertFalse(m3.isExported("p3"));
+ assertFalse(m3.isOpen("p3"));
}
/**
@@ -144,6 +181,18 @@
// java.base is not in layer
try {
+ controller.addExports(base, "java.lang", m2);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+
+ // m1 does not contain java.lang
+ try {
+ controller.addExports(m1, "java.lang", m2);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+
+ // java.base is not in layer
+ try {
controller.addOpens(base, "java.lang", m2);
assertTrue(false);
} catch (IllegalArgumentException expected) { }
@@ -177,6 +226,21 @@
} catch (NullPointerException expected) { }
try {
+ controller.addExports(null, "p1", m2);
+ assertTrue(false);
+ } catch (NullPointerException expected) { }
+
+ try {
+ controller.addExports(m1, null, m2);
+ assertTrue(false);
+ } catch (NullPointerException expected) { }
+
+ try {
+ controller.addExports(m1, "p1", null);
+ assertTrue(false);
+ } catch (NullPointerException expected) { }
+
+ try {
controller.addOpens(null, "p1", m2);
assertTrue(false);
} catch (NullPointerException expected) { }
--- a/jdk/test/java/lang/ModuleTests/AnnotationsTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleTests/AnnotationsTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -62,6 +62,7 @@
public void testUnnamedModule() {
Module module = this.getClass().getModule();
assertTrue(module.getAnnotations().length == 0);
+ assertTrue(module.getDeclaredAnnotations().length == 0);
}
/**
@@ -88,6 +89,7 @@
Annotation[] a = module.getAnnotations();
assertTrue(a.length == 1);
assertTrue(a[0] instanceof Deprecated);
+ assertEquals(module.getDeclaredAnnotations(), a);
}
--- a/jdk/test/java/lang/ModuleTests/BasicModuleTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleTests/BasicModuleTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -35,7 +35,7 @@
* @test
* @summary Basic test of java.lang.Module
* @modules java.desktop java.xml
- * @run testng BasicModuleTest
+ * @run testng/othervm --illegal-access=deny BasicModuleTest
*/
public class BasicModuleTest {
--- a/jdk/test/java/lang/ModuleTests/annotation/Basic.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/ModuleTests/annotation/Basic.java Fri Jun 16 09:20:39 2017 -0700
@@ -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
@@ -29,7 +29,7 @@
* @summary Basic test for annotations on modules
*/
-import java.util.Arrays;
+import java.lang.annotation.Annotation;
import p.annotation.Foo;
import p.annotation.Bar;
@@ -71,6 +71,28 @@
Baz baz = module.getAnnotation(Baz.class);
assertNotNull(baz);
String[] expected = { "one", "two", "three" };
- assertTrue(Arrays.equals(baz.value(), expected));
+ assertEquals(baz.value(), expected);
+ }
+
+ /**
+ * Test annotations with RUNTIME retention policy
+ */
+ @Test
+ public void testRuntimeAnnotations() {
+ Annotation[] a = module.getAnnotations();
+ assertEquals(a, module.getDeclaredAnnotations());
+ assertTrue(a.length == 2);
+ Bar bar;
+ Baz baz;
+ if (a[0] instanceof Bar) {
+ bar = (Bar)a[0];
+ baz = (Baz)a[1];
+ } else {
+ bar = (Bar)a[1];
+ baz = (Baz)a[0];
+ }
+ assertEquals(bar.value(), "bar");
+ String[] expected = { "one", "two", "three"};
+ assertEquals(baz.value(), expected);
}
}
--- a/jdk/test/java/lang/instrument/RedefineModuleTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/instrument/RedefineModuleTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -29,7 +29,7 @@
* java.base/jdk.internal.test.TestProviderImpl1
* java.base/jdk.internal.test.TestProviderImpl2
* @run shell MakeJAR3.sh RedefineModuleAgent
- * @run testng/othervm -javaagent:RedefineModuleAgent.jar RedefineModuleTest
+ * @run testng/othervm --illegal-access=deny -javaagent:RedefineModuleAgent.jar RedefineModuleTest
*/
import java.lang.TestProvider;
--- a/jdk/test/java/lang/module/AutomaticModulesTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/module/AutomaticModulesTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -58,8 +58,8 @@
private static final Path USER_DIR
= Paths.get(System.getProperty("user.dir"));
- @DataProvider(name = "names")
- public Object[][] createNames() {
+ @DataProvider(name = "jarnames")
+ public Object[][] createJarNames() {
return new Object[][] {
// JAR file name module-name[/version]
@@ -100,7 +100,7 @@
}
// JAR file names that do not map to a legal module name
- @DataProvider(name = "badnames")
+ @DataProvider(name = "badjarnames")
public Object[][] createBadNames() {
return new Object[][]{
@@ -117,7 +117,7 @@
/**
* Test mapping of JAR file names to module names
*/
- @Test(dataProvider = "names")
+ @Test(dataProvider = "jarnames")
public void testNames(String fn, String mid) throws IOException {
String[] s = mid.split("/");
String mn = s[0];
@@ -146,11 +146,10 @@
}
}
-
/**
* Test impossible mapping of JAR files to modules names
*/
- @Test(dataProvider = "badnames", expectedExceptions = FindException.class)
+ @Test(dataProvider = "badjarnames", expectedExceptions = FindException.class)
public void testBadNames(String fn, String ignore) throws IOException {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path jf = dir.resolve(fn);
@@ -163,6 +162,76 @@
}
+ @DataProvider(name = "modulenames")
+ public Object[][] createModuleNames() {
+ return new Object[][] {
+ { "foo", null },
+ { "foo", "1.0" },
+ { "foo.bar", null },
+ { "foo.bar", "1.0" },
+ { "class_", null },
+ { "class_", "1.0" },
+ };
+ }
+
+ @DataProvider(name = "badmodulenames")
+ public Object[][] createBadModuleNames() {
+ return new Object[][] {
+ { "", null },
+ { "", "1.0" },
+ { "666", null },
+ { "666", "1.0" },
+ { "foo.class", null },
+ { "foo.class", "1.0" },
+ };
+ }
+
+ /**
+ * Test JAR files with the Automatic-Module-Name attribute
+ */
+ @Test(dataProvider = "modulenames")
+ public void testAutomaticModuleNameAttribute(String name, String vs)
+ throws IOException
+ {
+ Manifest man = new Manifest();
+ Attributes attrs = man.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
+ attrs.put(new Attributes.Name("Automatic-Module-Name"), name);
+
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ String jar;
+ if (vs == null) {
+ jar = "m.jar";
+ } else {
+ jar = "m-" + vs + ".jar";
+ }
+ createDummyJarFile(dir.resolve(jar), man);
+
+ ModuleFinder finder = ModuleFinder.of(dir);
+
+ assertTrue(finder.findAll().size() == 1);
+ assertTrue(finder.find(name).isPresent());
+
+ ModuleReference mref = finder.find(name).get();
+ ModuleDescriptor descriptor = mref.descriptor();
+ assertEquals(descriptor.name(), name);
+ assertEquals(descriptor.version()
+ .map(ModuleDescriptor.Version::toString)
+ .orElse(null), vs);
+ }
+
+ /**
+ * Test JAR files with the Automatic-Module-Name attribute with a value
+ * that is not a legal module name.
+ */
+ @Test(dataProvider = "badmodulenames", expectedExceptions = FindException.class)
+ public void testBadAutomaticModuleNameAttribute(String name, String ignore)
+ throws IOException
+ {
+ // should throw FindException
+ testAutomaticModuleNameAttribute(name, null);
+ }
+
/**
* Test all packages are exported
*/
@@ -277,7 +346,6 @@
assertTrue(provides.providers().contains((provider)));
}
-
// META-INF/services files that don't map to legal service names
@DataProvider(name = "badservices")
public Object[][] createBadServices() {
@@ -310,7 +378,6 @@
assertTrue(descriptor.provides().isEmpty());
}
-
// META-INF/services configuration file entries that are not legal
@DataProvider(name = "badproviders")
public Object[][] createBadProviders() {
@@ -370,7 +437,6 @@
ModuleFinder.of(dir).findAll();
}
-
/**
* Test that a JAR file with a Main-Class attribute results
* in a module with a main class.
@@ -398,7 +464,6 @@
assertEquals(descriptor.mainClass().get(), mainClass);
}
-
// Main-Class files that do not map to a legal qualified type name
@DataProvider(name = "badmainclass")
public Object[][] createBadMainClass() {
@@ -450,7 +515,6 @@
assertFalse(descriptor.mainClass().isPresent());
}
-
/**
* Basic test of a configuration created with automatic modules.
* a requires b*
@@ -583,7 +647,6 @@
testReadAllBootModules(cf, "d"); // d reads all modules in boot layer
}
-
/**
* Basic test of a configuration created with automatic modules
* a requires b
@@ -662,7 +725,6 @@
testReadAllBootModules(cf, "d"); // d reads all modules in boot layer
}
-
/**
* Basic test to ensure that no automatic modules are resolved when
* an automatic module is not a root or required by other modules.
@@ -692,7 +754,6 @@
assertTrue(cf.findModule("m1").isPresent());
}
-
/**
* Basic test to ensure that if an automatic module is resolved then
* all observable automatic modules are resolved.
@@ -770,7 +831,6 @@
assertTrue(auto3.reads().contains(base));
}
-
/**
* Basic test of automatic modules in a child configuration. All automatic
* modules that are found with the before finder should be resolved. The
@@ -845,7 +905,6 @@
assertTrue(auto3.reads().contains(base));
}
-
/**
* Basic test of a configuration created with automatic modules
* a requires b* and c*
@@ -874,7 +933,6 @@
resolve(parent, finder, "a");
}
-
/**
* Basic test of a configuration created with automatic modules
* a contains p, requires b*
@@ -901,7 +959,6 @@
resolve(parent, finder, "a");
}
-
/**
* Basic test of layer containing automatic modules
*/
@@ -943,7 +1000,6 @@
testsReadsAll(c, layer);
}
-
/**
* Test miscellaneous methods.
*/
@@ -961,7 +1017,6 @@
assertFalse(m.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC));
}
-
/**
* Invokes parent.resolve to resolve the given root modules.
*/
@@ -1055,7 +1110,7 @@
* in the resulting JAR file.
*/
static Path createDummyJarFile(Path jarfile, String... entries)
- throws IOException
+ throws IOException
{
return createDummyJarFile(jarfile, null, entries);
}
--- a/jdk/test/java/lang/reflect/AccessibleObject/CanAccessTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/CanAccessTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -25,7 +25,7 @@
* @test
* @build CanAccessTest
* @modules java.base/jdk.internal.misc:+open
- * @run testng CanAccessTest
+ * @run testng/othervm --illegal-access=deny CanAccessTest
* @summary Test AccessibleObject::canAccess method
*/
--- a/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -26,7 +26,7 @@
* @build ModuleSetAccessibleTest
* @modules java.base/java.lang:open
* java.base/jdk.internal.misc:+open
- * @run testng ModuleSetAccessibleTest
+ * @run testng/othervm --illegal-access=deny ModuleSetAccessibleTest
* @summary Test java.lang.reflect.AccessibleObject with modules
*/
--- a/jdk/test/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -27,7 +27,7 @@
* @modules java.base/java.lang:open
* java.base/jdk.internal.perf
* java.base/jdk.internal.misc:+open
- * @run testng TrySetAccessibleTest
+ * @run testng/othervm --illegal-access=deny TrySetAccessibleTest
* @summary Test AccessibleObject::trySetAccessible method
*/
--- a/jdk/test/java/util/ResourceBundle/modules/cache/CacheTest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/java/util/ResourceBundle/modules/cache/CacheTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -89,6 +89,7 @@
assertTrue(executeTestJava("--class-path", MODS_DIR.resolve(TEST_MODULE).toString(),
"--module-path", MODS_DIR.resolve(MAIN_BUNDLES_MODULE).toString(),
"--add-modules", MAIN_BUNDLES_MODULE,
+ "--illegal-access=deny",
MAIN_CLASS, "cache")
.outputTo(System.out)
.errorTo(System.out)
@@ -111,6 +112,7 @@
assertTrue(executeTestJava("--class-path", MODS_DIR.resolve(TEST_MODULE).toString(),
"--module-path", MODS_DIR.resolve(MAIN_BUNDLES_MODULE).toString(),
"--add-modules", MAIN_BUNDLES_MODULE,
+ "--illegal-access=deny",
MAIN_CLASS)
.outputTo(System.out)
.errorTo(System.out)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/BadProvidersTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,263 @@
+/*
+ * 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
+ * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * jdk.compiler
+ * @build CompilerUtils
+ * @run testng/othervm BadProvidersTest
+ * @summary Basic test of ServiceLoader with bad provider and bad provider
+ * factories deployed on the module path
+ */
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test of `provides S with PF` and `provides S with P` where the provider
+ * factory or provider
+ */
+
+public class BadProvidersTest {
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+
+ private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "modules");
+
+ private static final Path BADFACTORIES_DIR = Paths.get(TEST_SRC, "badfactories");
+ private static final Path BADPROVIDERS_DIR = Paths.get(TEST_SRC, "badproviders");
+
+ private static final String TEST1_MODULE = "test1";
+ private static final String TEST2_MODULE = "test2";
+
+ private static final String TEST_SERVICE = "p.Service";
+
+ /**
+ * Compiles a module, returning a module path with the compiled module.
+ */
+ private Path compileTest(String moduleName) throws Exception {
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ Path output = Files.createDirectory(dir.resolve(moduleName));
+ boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(moduleName), output);
+ assertTrue(compiled);
+ return dir;
+ }
+
+ /**
+ * Resolves a test module and loads it into its own layer. ServiceLoader
+ * is then used to load all providers.
+ */
+ private List<Provider> loadProviders(Path mp, String moduleName) throws Exception {
+ ModuleFinder finder = ModuleFinder.of(mp);
+
+ ModuleLayer bootLayer = ModuleLayer.boot();
+
+ Configuration cf = bootLayer.configuration()
+ .resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
+
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+
+ ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
+
+ Class<?> service = layer.findLoader(moduleName).loadClass(TEST_SERVICE);
+
+ return ServiceLoader.load(layer, service)
+ .stream()
+ .collect(Collectors.toList());
+ }
+
+ @Test
+ public void sanityTest1() throws Exception {
+ Path mods = compileTest(TEST1_MODULE);
+ List<Provider> list = loadProviders(mods, TEST1_MODULE);
+ assertTrue(list.size() == 1);
+
+ // the provider is a singleton, enforced by the provider factory
+ Object p1 = list.get(0).get();
+ Object p2 = list.get(0).get();
+ assertTrue(p1 != null);
+ assertTrue(p1 == p2);
+ }
+
+ @Test
+ public void sanityTest2() throws Exception {
+ Path mods = compileTest(TEST2_MODULE);
+ List<Provider> list = loadProviders(mods, TEST2_MODULE);
+ assertTrue(list.size() == 1);
+ Object p = list.get(0).get();
+ assertTrue(p != null);
+ }
+
+
+ @DataProvider(name = "badfactories")
+ public Object[][] createBadFactories() {
+ return new Object[][] {
+ { "classnotpublic", null },
+ { "methodnotpublic", null },
+ { "badreturntype", null },
+ { "returnsnull", null },
+ { "throwsexception", null },
+ };
+ }
+
+
+ @Test(dataProvider = "badfactories",
+ expectedExceptions = ServiceConfigurationError.class)
+ public void testBadFactory(String testName, String ignore) throws Exception {
+ Path mods = compileTest(TEST1_MODULE);
+
+ // compile the bad factory
+ Path source = BADFACTORIES_DIR.resolve(testName);
+ Path output = Files.createTempDirectory(USER_DIR, "tmp");
+ boolean compiled = CompilerUtils.compile(source, output);
+ assertTrue(compiled);
+
+ // copy the compiled class into the module
+ Path classFile = Paths.get("p", "ProviderFactory.class");
+ Files.copy(output.resolve(classFile),
+ mods.resolve(TEST1_MODULE).resolve(classFile),
+ StandardCopyOption.REPLACE_EXISTING);
+
+ // load providers and instantiate each one
+ loadProviders(mods, TEST1_MODULE).forEach(Provider::get);
+ }
+
+
+ @DataProvider(name = "badproviders")
+ public Object[][] createBadProviders() {
+ return new Object[][] {
+ { "notpublic", null },
+ { "ctornotpublic", null },
+ { "notasubtype", null },
+ { "throwsexception", null }
+ };
+ }
+
+
+ @Test(dataProvider = "badproviders",
+ expectedExceptions = ServiceConfigurationError.class)
+ public void testBadProvider(String testName, String ignore) throws Exception {
+ Path mods = compileTest(TEST2_MODULE);
+
+ // compile the bad provider
+ Path source = BADPROVIDERS_DIR.resolve(testName);
+ Path output = Files.createTempDirectory(USER_DIR, "tmp");
+ boolean compiled = CompilerUtils.compile(source, output);
+ assertTrue(compiled);
+
+ // copy the compiled class into the module
+ Path classFile = Paths.get("p", "Provider.class");
+ Files.copy(output.resolve(classFile),
+ mods.resolve(TEST2_MODULE).resolve(classFile),
+ StandardCopyOption.REPLACE_EXISTING);
+
+ // load providers and instantiate each one
+ loadProviders(mods, TEST2_MODULE).forEach(Provider::get);
+ }
+
+
+ /**
+ * Test a service provider that defines more than one no-args
+ * public static "provider" method.
+ */
+ @Test(expectedExceptions = ServiceConfigurationError.class)
+ public void testWithTwoFactoryMethods() throws Exception {
+ Path mods = compileTest(TEST1_MODULE);
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ + ClassWriter.COMPUTE_FRAMES);
+ cw.visit(V1_9,
+ ACC_PUBLIC + ACC_SUPER,
+ "p/ProviderFactory",
+ null,
+ "java/lang/Object",
+ null);
+
+ // public static p.Service provider()
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
+ "provider",
+ "()Lp/Service;",
+ null,
+ null);
+ mv.visitTypeInsn(NEW, "p/ProviderFactory$1");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL,
+ "p/ProviderFactory$1",
+ "<init>", "()V",
+ false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ // public static p.ProviderFactory$1 provider()
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
+ "provider",
+ "()Lp/ProviderFactory$1;",
+ null,
+ null);
+ mv.visitTypeInsn(NEW, "p/ProviderFactory$1");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL,
+ "p/ProviderFactory$1",
+ "<init>",
+ "()V",
+ false);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ cw.visitEnd();
+
+ // write the class bytes into the compiled module directory
+ Path classFile = mods.resolve(TEST1_MODULE)
+ .resolve("p")
+ .resolve("ProviderFactory.class");
+ Files.write(classFile, cw.toByteArray());
+
+ // load providers and instantiate each one
+ loadProviders(mods, TEST1_MODULE).forEach(Provider::get);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/ModulesTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,479 @@
+/*
+ * 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
+ * @modules java.scripting
+ * @library modules /lib/testlibrary
+ * @build bananascript/*
+ * @build JarUtils
+ * @compile classpath/pearscript/org/pear/PearScriptEngineFactory.java
+ * classpath/pearscript/org/pear/PearScript.java
+ * @run testng/othervm ModulesTest
+ * @summary Basic test for ServiceLoader with a provider deployed as a module.
+ */
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+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.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.script.ScriptEngineFactory;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeTest;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test for ServiceLoader. The test make use of two service providers:
+ * 1. BananaScriptEngine - a ScriptEngineFactory deployed as a module on the
+ * module path. It implementations a singleton via the public static
+ * provider method.
+ * 2. PearScriptEngine - a ScriptEngineFactory deployed on the class path
+ * with a service configuration file.
+ */
+
+public class ModulesTest {
+
+ // Copy the services configuration file for "pearscript" into place.
+ @BeforeTest
+ public void setup() throws Exception {
+ Path src = Paths.get(System.getProperty("test.src"));
+ Path classes = Paths.get(System.getProperty("test.classes"));
+ String st = ScriptEngineFactory.class.getName();
+ Path config = Paths.get("META-INF", "services", st);
+ Path source = src.resolve("classpath").resolve("pearscript").resolve(config);
+ Path target = classes.resolve(config);
+ Files.createDirectories(target.getParent());
+ Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ /**
+ * Basic test of iterator() to ensure that providers located as modules
+ * and on the class path are found.
+ */
+ @Test
+ public void testIterator() {
+ ServiceLoader<ScriptEngineFactory> loader
+ = ServiceLoader.load(ScriptEngineFactory.class);
+ Set<String> names = collectAll(loader)
+ .stream()
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertTrue(names.contains("BananaScriptEngine"));
+ assertTrue(names.contains("PearScriptEngine"));
+ }
+
+ /**
+ * Basic test of iterator() to test iteration order. Providers deployed
+ * as named modules should be found before providers deployed on the class
+ * path.
+ */
+ @Test
+ public void testIteratorOrder() {
+ ServiceLoader<ScriptEngineFactory> loader
+ = ServiceLoader.load(ScriptEngineFactory.class);
+ boolean foundUnnamed = false;
+ for (ScriptEngineFactory factory : collectAll(loader)) {
+ if (factory.getClass().getModule().isNamed()) {
+ if (foundUnnamed) {
+ assertTrue(false, "Named module element after unnamed");
+ }
+ } else {
+ foundUnnamed = true;
+ }
+ }
+ }
+
+ /**
+ * Basic test of Provider::type
+ */
+ @Test
+ public void testProviderType() {
+ Set<String> types = ServiceLoader.load(ScriptEngineFactory.class)
+ .stream()
+ .map(Provider::type)
+ .map(Class::getName)
+ .collect(Collectors.toSet());
+ assertTrue(types.contains("org.banana.BananaScriptEngineFactory"));
+ assertTrue(types.contains("org.pear.PearScriptEngineFactory"));
+ }
+
+ /**
+ * Basic test of Provider::get
+ */
+ @Test
+ public void testProviderGet() {
+ Set<String> names = ServiceLoader.load(ScriptEngineFactory.class)
+ .stream()
+ .map(Provider::get)
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertTrue(names.contains("BananaScriptEngine"));
+ assertTrue(names.contains("PearScriptEngine"));
+ }
+
+ /**
+ * Basic test of the public static provider method. BananaScriptEngine
+ * defines a provider method that returns the same instance.
+ */
+ @Test
+ public void testSingleton() {
+ Optional<Provider<ScriptEngineFactory>> oprovider
+ = ServiceLoader.load(ScriptEngineFactory.class)
+ .stream()
+ .filter(p -> p.type().getName().equals("org.banana.BananaScriptEngineFactory"))
+ .findFirst();
+ assertTrue(oprovider.isPresent());
+ Provider<ScriptEngineFactory> provider = oprovider.get();
+
+ // invoke Provider::get twice
+ ScriptEngineFactory factory1 = provider.get();
+ ScriptEngineFactory factory2 = provider.get();
+ assertTrue(factory1 == factory2);
+ }
+
+ /**
+ * Basic test of stream() to ensure that elements for providers in named
+ * modules come before elements for providers in unnamed modules.
+ */
+ @Test
+ public void testStreamOrder() {
+ List<Class<?>> types = ServiceLoader.load(ScriptEngineFactory.class)
+ .stream()
+ .map(Provider::type)
+ .collect(Collectors.toList());
+
+ boolean foundUnnamed = false;
+ for (Class<?> factoryClass : types) {
+ if (factoryClass.getModule().isNamed()) {
+ if (foundUnnamed) {
+ assertTrue(false, "Named module element after unnamed");
+ }
+ } else {
+ foundUnnamed = true;
+ }
+ }
+ }
+
+ /**
+ * Basic test of ServiceLoader.findFirst()
+ */
+ @Test
+ public void testFindFirst() {
+ Optional<ScriptEngineFactory> ofactory
+ = ServiceLoader.load(ScriptEngineFactory.class).findFirst();
+ assertTrue(ofactory.isPresent());
+ ScriptEngineFactory factory = ofactory.get();
+ assertTrue(factory.getClass().getModule().isNamed());
+
+ class S { }
+ assertFalse(ServiceLoader.load(S.class).findFirst().isPresent());
+ }
+
+ /**
+ * Basic test ServiceLoader.load specifying the platform class loader.
+ * The providers on the module path and class path should not be located.
+ */
+ @Test
+ public void testWithPlatformClassLoader() {
+ ClassLoader pcl = ClassLoader.getPlatformClassLoader();
+
+ // iterator
+ ServiceLoader<ScriptEngineFactory> loader
+ = ServiceLoader.load(ScriptEngineFactory.class, pcl);
+ Set<String> names = collectAll(loader)
+ .stream()
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertFalse(names.contains("BananaScriptEngine"));
+ assertFalse(names.contains("PearScriptEngine"));
+
+ // stream
+ names = ServiceLoader.load(ScriptEngineFactory.class, pcl)
+ .stream()
+ .map(Provider::get)
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertFalse(names.contains("BananaScriptEngine"));
+ assertFalse(names.contains("PearScriptEngine"));
+ }
+
+ /**
+ * Basic test of ServiceLoader.load where the service provider module is an
+ * automatic module.
+ */
+ @Test
+ public void testWithAutomaticModule() throws Exception {
+ Path classes = Paths.get(System.getProperty("test.classes"));
+ Path jar = Files.createTempDirectory("lib").resolve("pearscript.jar");
+ JarUtils.createJarFile(jar, classes, "META-INF", "org");
+
+ ModuleFinder finder = ModuleFinder.of(jar);
+ ModuleLayer bootLayer = ModuleLayer.boot();
+ Configuration parent = bootLayer.configuration();
+ Configuration cf = parent.resolveAndBind(finder, ModuleFinder.of(), Set.of());
+ assertTrue(cf.modules().size() == 1);
+
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
+ assertTrue(layer.modules().size() == 1);
+
+ ClassLoader loader = layer.findLoader("pearscript");
+ ScriptEngineFactory factory;
+
+ // load using the class loader as context
+ factory = ServiceLoader.load(ScriptEngineFactory.class, loader)
+ .findFirst()
+ .orElse(null);
+ assertNotNull(factory);
+ assertTrue(factory.getClass().getClassLoader() == loader);
+
+ // load using the layer as context
+ factory = ServiceLoader.load(layer, ScriptEngineFactory.class)
+ .findFirst()
+ .orElse(null);
+ assertNotNull(factory);
+ assertTrue(factory.getClass().getClassLoader() == loader);
+ }
+
+ /**
+ * Basic test of ServiceLoader.load, using the class loader for
+ * a module in a custom layer as the context.
+ */
+ @Test
+ public void testWithCustomLayer1() {
+ ModuleLayer layer = createCustomLayer("bananascript");
+
+ ClassLoader loader = layer.findLoader("bananascript");
+ List<ScriptEngineFactory> providers
+ = collectAll(ServiceLoader.load(ScriptEngineFactory.class, loader));
+
+ // should have at least 2 x bananascript + pearscript
+ assertTrue(providers.size() >= 3);
+
+ // first element should be the provider in the custom layer
+ ScriptEngineFactory factory = providers.get(0);
+ assertTrue(factory.getClass().getClassLoader() == loader);
+ assertTrue(factory.getClass().getModule().getLayer() == layer);
+ assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
+
+ // remainder should be the boot layer
+ providers.remove(0);
+ Set<String> names = providers.stream()
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertTrue(names.contains("BananaScriptEngine"));
+ assertTrue(names.contains("PearScriptEngine"));
+ }
+
+ /**
+ * Basic test of ServiceLoader.load using a custom Layer as the context.
+ */
+ @Test
+ public void testWithCustomLayer2() {
+ ModuleLayer layer = createCustomLayer("bananascript");
+
+ List<ScriptEngineFactory> factories
+ = collectAll(ServiceLoader.load(layer, ScriptEngineFactory.class));
+
+ // should have at least 2 x bananascript
+ assertTrue(factories.size() >= 2);
+
+ // first element should be the provider in the custom layer
+ ScriptEngineFactory factory = factories.get(0);
+ assertTrue(factory.getClass().getModule().getLayer() == layer);
+ assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
+
+ // remainder should be the boot layer
+ factories.remove(0);
+ Set<String> names = factories.stream()
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toSet());
+ assertTrue(names.contains("BananaScriptEngine"));
+ assertFalse(names.contains("PearScriptEngine"));
+ }
+
+ /**
+ * Basic test of ServiceLoader.load with a tree of layers.
+ *
+ * Test scenario:
+ * - boot layer contains "bananascript", maybe other script engines
+ * - layer1, with boot layer as parent, contains "bananascript"
+ * - layer2, with boot layer as parent, contains "bananascript"
+ * - layer3, with layer1 ad layer as parents, contains "bananascript"
+ *
+ * ServiceLoader should locate all 4 script engine factories in DFS order.
+ */
+ @Test
+ public void testWithCustomLayer3() {
+ ModuleLayer bootLayer = ModuleLayer.boot();
+ Configuration cf0 = bootLayer.configuration();
+
+ // boot layer should contain "bananascript"
+ List<ScriptEngineFactory> factories
+ = collectAll(ServiceLoader.load(bootLayer, ScriptEngineFactory.class));
+ int countInBootLayer = factories.size();
+ assertTrue(countInBootLayer >= 1);
+ assertTrue(factories.stream()
+ .map(p -> p.getEngineName())
+ .filter("BananaScriptEngine"::equals)
+ .findAny()
+ .isPresent());
+
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ Path dir = Paths.get(System.getProperty("test.classes", "."), "modules");
+ ModuleFinder finder = ModuleFinder.of(dir);
+
+ // layer1
+ Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
+ ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
+ assertTrue(layer1.modules().size() == 1);
+
+ // layer2
+ Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
+ ModuleLayer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
+ assertTrue(layer2.modules().size() == 1);
+
+ // layer3 with layer1 and layer2 as parents
+ Configuration cf3 = Configuration.resolveAndBind(finder,
+ List.of(cf1, cf2),
+ ModuleFinder.of(),
+ Set.of());
+ ModuleLayer layer3
+ = ModuleLayer.defineModulesWithOneLoader(cf3, List.of(layer1, layer2), scl).layer();
+ assertTrue(layer3.modules().size() == 1);
+
+
+ // class loaders
+ ClassLoader loader1 = layer1.findLoader("bananascript");
+ ClassLoader loader2 = layer2.findLoader("bananascript");
+ ClassLoader loader3 = layer3.findLoader("bananascript");
+ assertTrue(loader1 != loader2);
+ assertTrue(loader1 != loader3);
+ assertTrue(loader2 != loader3);
+
+ // load all factories with layer3 as the context
+ factories = collectAll(ServiceLoader.load(layer3, ScriptEngineFactory.class));
+ int count = factories.size();
+ assertTrue(count == countInBootLayer + 3);
+
+ // the ordering should be layer3, layer1, boot layer, layer2
+
+ ScriptEngineFactory factory = factories.get(0);
+ assertTrue(factory.getClass().getModule().getLayer() == layer3);
+ assertTrue(factory.getClass().getClassLoader() == loader3);
+ assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
+
+ factory = factories.get(1);
+ assertTrue(factory.getClass().getModule().getLayer() == layer1);
+ assertTrue(factory.getClass().getClassLoader() == loader1);
+ assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
+
+ // boot layer "bananascript" and maybe other factories
+ int last = count -1;
+ boolean found = false;
+ for (int i=2; i<last; i++) {
+ factory = factories.get(i);
+ assertTrue(factory.getClass().getModule().getLayer() == bootLayer);
+ if (factory.getEngineName().equals("BananaScriptEngine")) {
+ assertFalse(found);
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ factory = factories.get(last);
+ assertTrue(factory.getClass().getModule().getLayer() == layer2);
+ assertTrue(factory.getClass().getClassLoader() == loader2);
+ assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
+ }
+
+
+ // -- nulls --
+
+ @Test(expectedExceptions = { NullPointerException.class })
+ public void testLoadNull1() {
+ ServiceLoader.load(null);
+ }
+
+ @Test(expectedExceptions = { NullPointerException.class })
+ public void testLoadNull2() {
+ ServiceLoader.load((Class<?>) null, ClassLoader.getSystemClassLoader());
+ }
+
+ @Test(expectedExceptions = { NullPointerException.class })
+ public void testLoadNull3() {
+ class S { }
+ ServiceLoader.load((ModuleLayer) null, S.class);
+ }
+
+ @Test(expectedExceptions = { NullPointerException.class })
+ public void testLoadNull4() {
+ ServiceLoader.load(ModuleLayer.empty(), null);
+ }
+
+ @Test(expectedExceptions = { NullPointerException.class })
+ public void testLoadNull5() {
+ ServiceLoader.loadInstalled(null);
+ }
+
+ /**
+ * Create a custom layer by resolving the given module names. The modules
+ * are located in the {@code ${test.classes}/modules} directory.
+ */
+ private ModuleLayer createCustomLayer(String... modules) {
+ Path dir = Paths.get(System.getProperty("test.classes", "."), "modules");
+ ModuleFinder finder = ModuleFinder.of(dir);
+ Set<String> roots = new HashSet<>();
+ Collections.addAll(roots, modules);
+ ModuleLayer bootLayer = ModuleLayer.boot();
+ Configuration parent = bootLayer.configuration();
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
+ assertTrue(layer.modules().size() == 1);
+ return layer;
+ }
+
+ private <E> List<E> collectAll(ServiceLoader<E> loader) {
+ List<E> list = new ArrayList<>();
+ Iterator<E> iterator = loader.iterator();
+ while (iterator.hasNext()) {
+ list.add(iterator.next());
+ }
+ return list;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/NoInterferenceTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,151 @@
+/*
+ * 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
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build CompilerUtils
+ * @run testng NoInterferenceTest
+ * @summary Basic test of ServiceLoader that ensures there is no interference
+ * when there are two service interfaces of the same name in a layer
+ * or overridden in a child layer.
+ */
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class NoInterferenceTest {
+
+ private static final String TEST_SRC = System.getProperty("test.src");
+ private static final Path SRC_DIR = Paths.get(TEST_SRC, "modules");
+ private static final Path MODS_DIR = Paths.get("mods");
+ private static final List<String> MODULES = Arrays.asList("s1", "p1", "s2", "p2");
+
+ @BeforeTest
+ void compile() throws Exception {
+ Files.createDirectory(MODS_DIR);
+ for (String name : MODULES) {
+ Path src = SRC_DIR.resolve(name);
+ Path output = Files.createDirectory(MODS_DIR.resolve(name));
+ assertTrue(CompilerUtils.compile(src, output, "-p", MODS_DIR.toString()));
+ }
+ }
+
+ @Test
+ public void test() throws Exception {
+ ModuleFinder empty = ModuleFinder.of();
+ ModuleFinder finder = ModuleFinder.of(MODS_DIR);
+
+ ModuleLayer bootLayer = ModuleLayer.boot();
+
+ Configuration cf0 = bootLayer.configuration();
+ Configuration cf1 = cf0.resolveAndBind(finder, empty, Set.of("s1", "s2"));
+ Configuration cf2 = cf1.resolveAndBind(finder, empty, Set.of("s1", "s2"));
+
+ // cf1 contains s1, p1, s2, p2
+ assertTrue(cf1.modules().size() == 4);
+
+ // cf1 contains s1, p1, s2, p2
+ assertTrue(cf2.modules().size() == 4);
+
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+
+ ModuleLayer layer1 = bootLayer.defineModulesWithManyLoaders(cf1, scl);
+ testLayer(layer1);
+
+ ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, scl);
+ testLayer(layer2);
+ }
+
+ /**
+ * Tests that the layer contains s1, p1, s2, and p2.
+ *
+ * Tests loading instances of s1/p.S and s2/p.S.
+ */
+ private void testLayer(ModuleLayer layer) throws Exception {
+ assertTrue(layer.modules().size() == 4);
+ Module s1 = layer.findModule("s1").get();
+ Module p1 = layer.findModule("p1").get();
+ Module s2 = layer.findModule("s2").get();
+ Module p2 = layer.findModule("p2").get();
+
+ // p1 reads s1
+ assertTrue(p1.canRead(s1));
+ assertFalse(p1.canRead(s2));
+
+ // p2 reads s2
+ assertTrue(p2.canRead(s2));
+ assertFalse(p2.canRead(s1));
+
+ // iterate over implementations of s1/p.S
+ {
+ ClassLoader loader = layer.findLoader("s1");
+ Class<?> service = loader.loadClass("p.S");
+
+ List<?> list = collectAll(ServiceLoader.load(service, loader));
+ assertTrue(list.size() == 1);
+ assertTrue(list.get(0).getClass().getModule() == p1);
+
+ list = collectAll(ServiceLoader.load(layer, service));
+ assertTrue(list.size() == 1);
+ assertTrue(list.get(0).getClass().getModule() == p1);
+ }
+
+ // iterate over implementations of s2/p.S
+ {
+ ClassLoader loader = layer.findLoader("s2");
+ Class<?> service = loader.loadClass("p.S");
+
+ List<?> list = collectAll(ServiceLoader.load(service, loader));
+ assertTrue(list.size() == 1);
+ assertTrue(list.get(0).getClass().getModule() == p2);
+
+ list = collectAll(ServiceLoader.load(layer, service));
+ assertTrue(list.size() == 1);
+ assertTrue(list.get(0).getClass().getModule() == p2);
+ }
+ }
+
+ private <E> List<E> collectAll(ServiceLoader<E> loader) {
+ List<E> list = new ArrayList<>();
+ Iterator<E> iterator = loader.iterator();
+ while (iterator.hasNext()) {
+ list.add(iterator.next());
+ }
+ return list;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/ReloadTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,98 @@
+/*
+ * 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
+ * @library modules
+ * @modules java.scripting
+ * @run testng/othervm ReloadTest
+ * @summary Basic test of ServiceLoader.reload
+ */
+
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.Spliterator;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static java.util.ServiceLoader.*;
+import javax.script.ScriptEngineFactory;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class ReloadTest {
+
+ public void testReload() {
+ ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
+ List<String> names1 = sl.stream()
+ .map(Provider::get)
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toList());
+ assertFalse(names1.isEmpty());
+ sl.reload();
+ List<String> names2 = sl.stream()
+ .map(Provider::get)
+ .map(ScriptEngineFactory::getEngineName)
+ .collect(Collectors.toList());
+ assertEquals(names1, names2);
+ }
+
+ @Test(expectedExceptions = { ConcurrentModificationException.class })
+ public void testIteratorHasNext() {
+ ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
+ Iterator<ScriptEngineFactory> iterator = sl.iterator();
+ sl.reload();
+ iterator.hasNext();
+ }
+
+ @Test(expectedExceptions = { ConcurrentModificationException.class })
+ public void testIteratorNext() {
+ ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
+ Iterator<ScriptEngineFactory> iterator = sl.iterator();
+ assertTrue(iterator.hasNext());
+ sl.reload();
+ iterator.next();
+ }
+
+ @Test(expectedExceptions = { ConcurrentModificationException.class })
+ public void testStreamFindAny() {
+ ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
+ Stream<Provider<ScriptEngineFactory>> stream = sl.stream();
+ sl.reload();
+ stream.findAny();
+ }
+
+ @Test(expectedExceptions = { ConcurrentModificationException.class })
+ public void testSpliteratorTryAdvance() {
+ ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
+ Stream<Provider<ScriptEngineFactory>> stream = sl.stream();
+ Spliterator<Provider<ScriptEngineFactory>> spliterator = stream.spliterator();
+ sl.reload();
+ spliterator.tryAdvance(System.out::println);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/badreturntype/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 p;
+
+/**
+ * A provider factory with a provider() method with a return type that is not
+ * p.Service
+ */
+
+public class ProviderFactory {
+ ProviderFactory() { }
+
+ public static Object provider() {
+ throw new RuntimeException("Should not be called");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/classnotpublic/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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 p;
+
+/**
+ * Not a provider factory because the class is not public.
+ */
+
+class ProviderFactory {
+ ProviderFactory() { }
+
+ public static Service provider() {
+ throw new RuntimeException("Should not be called");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/classnotpublic/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/methodnotpublic/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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 p;
+
+/**
+ * Not a provider factory because the static provider() method is not public.
+ */
+
+public class ProviderFactory {
+ ProviderFactory() { }
+
+ static Service provider() {
+ throw new RuntimeException("Should not be called");
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/methodnotpublic/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/returnsnull/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 p;
+
+/**
+ * A provider factory that defines a public static provider method that returns
+ * null.
+ */
+
+public class ProviderFactory {
+ ProviderFactory() { }
+
+ public static Service provider() {
+ return null;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/returnsnull/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/throwsexception/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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 p;
+
+/**
+ * A provider factory that throws an exception.
+ */
+
+public class ProviderFactory {
+ ProviderFactory() { }
+
+ public static Service provider() {
+ throw new RuntimeException();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badfactories/throwsexception/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/ctornotpublic/Provider.java Fri Jun 16 09:20:39 2017 -0700
@@ -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 p;
+
+/**
+ * A provider class with a non-public constructor
+ */
+
+public class Provider implements Service {
+ Provider() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/ctornotpublic/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/notasubtype/Provider.java Fri Jun 16 09:20:39 2017 -0700
@@ -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 p;
+
+/**
+ * A provider class that is not a subtype of Service.
+ */
+
+public class Provider {
+ Provider() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/notpublic/Provider.java Fri Jun 16 09:20:39 2017 -0700
@@ -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 p;
+
+/**
+ * Provider class not public.
+ */
+
+class Provider implements Service {
+ public Provider() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/notpublic/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/throwsexception/Provider.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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 p;
+
+/**
+ * A provider class with a constructor throws an exception.
+ */
+
+public class Provider {
+ public Provider() {
+ throw new RuntimeException();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/badproviders/throwsexception/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/classpath/pearscript/META-INF/services/javax.script.ScriptEngineFactory Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,1 @@
+org.pear.PearScriptEngineFactory
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/classpath/pearscript/org/pear/PearScript.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.pear;
+
+import java.io.Reader;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+public class PearScript implements ScriptEngine {
+
+ @Override
+ public Object eval(String script, ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader , ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(String script) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(String script, Bindings n) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader , Bindings n) {
+ throw new RuntimeException();
+ }
+ @Override
+ public void put(String key, Object value) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object get(String key) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Bindings getBindings(int scope) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void setBindings(Bindings bindings, int scope) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Bindings createBindings() {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptContext getContext() {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void setContext(ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptEngineFactory getFactory() {
+ throw new RuntimeException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/classpath/pearscript/org/pear/PearScriptEngineFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.pear;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+public class PearScriptEngineFactory implements ScriptEngineFactory {
+
+ public PearScriptEngineFactory() { }
+
+ public static PearScriptEngineFactory provider() {
+ throw new RuntimeException("Should not be called");
+ }
+
+ @Override
+ public String getEngineName() {
+ return "PearScriptEngine";
+ }
+
+ @Override
+ public String getEngineVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public List<String> getExtensions() {
+ return Arrays.asList("pear");
+ }
+
+ @Override
+ public List<String> getMimeTypes() {
+ return Arrays.asList("application/x-pearscript");
+ }
+
+ @Override
+ public List<String> getNames() {
+ return Arrays.asList("PearScript");
+ }
+
+ @Override
+ public String getLanguageName() {
+ return "PearScript";
+ }
+
+ @Override
+ public String getLanguageVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public Object getParameter(String key) {
+ return null;
+ }
+
+ @Override
+ public String getMethodCallSyntax(String obj, String m, String... args) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public String getOutputStatement(String toDisplay) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public String getProgram(String... statements) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine() {
+ return new PearScript();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/inheritance/NoInheritanceTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,30 @@
+/*
+ * 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
+ * @build test/*
+ * @run main/othervm test/p.Main
+ * @summary Basic test of ServiceLoader to ensure that static provider methods
+ * are explicitly declared and not inherited from super classes
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/inheritance/test/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,30 @@
+/*
+ * 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 p.Main.*;
+
+module test {
+ exports p;
+ uses S;
+ provides S with P1, P2, P3;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/inheritance/test/p/Main.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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 p;
+
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.stream.Collectors;
+
+/**
+ * Basic test of ServiceLoader with a provider interface and 3 provider
+ * implementations.
+ *
+ * The provider interface (test.Main.Provider) defines a static factory method
+ * name "provider" that locates a provider implementation. At least one of the
+ * provider implementations does not define a static "provider" method.
+ */
+
+public class Main {
+ public static void main(String[] args) {
+ List<S> providers = ServiceLoader.load(S.class).stream()
+ .map(ServiceLoader.Provider::get)
+ .collect(Collectors.toList());
+ if (providers.size() != 3)
+ throw new RuntimeException("Expected 3 providers");
+ }
+
+ /**
+ * Service type
+ */
+ public static interface S {
+ }
+
+ /**
+ * Base implementation, its static provider method should never be called
+ */
+ public static class BaseProvider implements S {
+ protected BaseProvider() { }
+ public static S provider() {
+ throw new RuntimeException("Should not get here");
+ }
+ }
+
+ /**
+ * Provider implementation with public constructor.
+ */
+ public static class P1 extends BaseProvider {
+ public P1() { }
+ }
+
+ /**
+ * Provider implementation with static factory method.
+ */
+ public static class P2 extends BaseProvider {
+ private P2() { }
+ public static P2 provider() {
+ return new P2();
+ }
+ }
+
+ /**
+ * Provider implementation with static factory method and public
+ * constructor.
+ */
+ public static class P3 extends BaseProvider {
+ public P3() {
+ throw new RuntimeException("Should not get here");
+ }
+ private P3(int x) { }
+ public static S provider() {
+ return new P3(0);
+ }
+ }
+}
--- a/jdk/test/java/util/ServiceLoader/modules/BadProvidersTest.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +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
- * @library /lib/testlibrary
- * @modules jdk.compiler
- * @build CompilerUtils
- * @run testng/othervm BadProvidersTest
- * @summary Basic test of ServiceLoader with bad provider and bad provider
- * factories deployed on the module path
- */
-
-import java.lang.module.Configuration;
-import java.lang.module.ModuleFinder;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.List;
-import java.util.ServiceConfigurationError;
-import java.util.ServiceLoader;
-import java.util.ServiceLoader.Provider;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-import static org.testng.Assert.*;
-
-/**
- * Basic test of `provides S with PF` and `provides S with P` where the provider
- * factory or provider
- */
-
-public class BadProvidersTest {
-
- private static final String TEST_SRC = System.getProperty("test.src");
-
- private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
- private static final Path SRC_DIR = Paths.get(TEST_SRC, "modules");
-
- private static final Path BADFACTORIES_DIR = Paths.get(TEST_SRC, "badfactories");
- private static final Path BADPROVIDERS_DIR = Paths.get(TEST_SRC, "badproviders");
-
- private static final String TEST1_MODULE = "test1";
- private static final String TEST2_MODULE = "test2";
-
- private static final String TEST_SERVICE = "p.Service";
-
- /**
- * Compiles a module, returning a module path with the compiled module.
- */
- private Path compileTest(String moduleName) throws Exception {
- Path dir = Files.createTempDirectory(USER_DIR, "mods");
- Path output = Files.createDirectory(dir.resolve(moduleName));
- boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(moduleName), output);
- assertTrue(compiled);
- return dir;
- }
-
- /**
- * Resolves a test module and loads it into its own layer. ServiceLoader
- * is then used to load all providers.
- */
- private List<Provider> loadProviders(Path mp, String moduleName) throws Exception {
- ModuleFinder finder = ModuleFinder.of(mp);
-
- ModuleLayer bootLayer = ModuleLayer.boot();
-
- Configuration cf = bootLayer.configuration()
- .resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
-
- ClassLoader scl = ClassLoader.getSystemClassLoader();
-
- ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
-
- Class<?> service = layer.findLoader(moduleName).loadClass(TEST_SERVICE);
-
- return ServiceLoader.load(layer, service)
- .stream()
- .collect(Collectors.toList());
- }
-
- @Test
- public void sanityTest1() throws Exception {
- Path mods = compileTest(TEST1_MODULE);
- List<Provider> list = loadProviders(mods, TEST1_MODULE);
- assertTrue(list.size() == 1);
-
- // the provider is a singleton, enforced by the provider factory
- Object p1 = list.get(0).get();
- Object p2 = list.get(0).get();
- assertTrue(p1 != null);
- assertTrue(p1 == p2);
- }
-
- @Test
- public void sanityTest2() throws Exception {
- Path mods = compileTest(TEST2_MODULE);
- List<Provider> list = loadProviders(mods, TEST2_MODULE);
- assertTrue(list.size() == 1);
- Object p = list.get(0).get();
- assertTrue(p != null);
- }
-
-
- @DataProvider(name = "badfactories")
- public Object[][] createBadFactories() {
- return new Object[][] {
- { "classnotpublic", null },
- { "methodnotpublic", null },
- { "badreturntype", null },
- { "returnsnull", null },
- { "throwsexception", null },
- };
- }
-
-
- @Test(dataProvider = "badfactories",
- expectedExceptions = ServiceConfigurationError.class)
- public void testBadFactory(String testName, String ignore) throws Exception {
- Path mods = compileTest(TEST1_MODULE);
-
- // compile the bad factory
- Path source = BADFACTORIES_DIR.resolve(testName);
- Path output = Files.createTempDirectory(USER_DIR, "tmp");
- boolean compiled = CompilerUtils.compile(source, output);
- assertTrue(compiled);
-
- // copy the compiled class into the module
- Path classFile = Paths.get("p", "ProviderFactory.class");
- Files.copy(output.resolve(classFile),
- mods.resolve(TEST1_MODULE).resolve(classFile),
- StandardCopyOption.REPLACE_EXISTING);
-
- // load providers and instantiate each one
- loadProviders(mods, TEST1_MODULE).forEach(Provider::get);
- }
-
-
- @DataProvider(name = "badproviders")
- public Object[][] createBadProviders() {
- return new Object[][] {
- { "notpublic", null },
- { "ctornotpublic", null },
- { "notasubtype", null },
- { "throwsexception", null }
- };
- }
-
-
- @Test(dataProvider = "badproviders",
- expectedExceptions = ServiceConfigurationError.class)
- public void testBadProvider(String testName, String ignore) throws Exception {
- Path mods = compileTest(TEST2_MODULE);
-
- // compile the bad provider
- Path source = BADPROVIDERS_DIR.resolve(testName);
- Path output = Files.createTempDirectory(USER_DIR, "tmp");
- boolean compiled = CompilerUtils.compile(source, output);
- assertTrue(compiled);
-
- // copy the compiled class into the module
- Path classFile = Paths.get("p", "Provider.class");
- Files.copy(output.resolve(classFile),
- mods.resolve(TEST2_MODULE).resolve(classFile),
- StandardCopyOption.REPLACE_EXISTING);
-
- // load providers and instantiate each one
- loadProviders(mods, TEST2_MODULE).forEach(Provider::get);
- }
-
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/Basic.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +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
- * @library modules
- * @modules java.scripting
- * @build bananascript/*
- * @compile src/pearscript/org/pear/PearScriptEngineFactory.java
- * src/pearscript/org/pear/PearScript.java
- * @run testng/othervm Basic
- * @summary Basic test for ServiceLoader with a provider deployed as a module.
- */
-
-import java.lang.module.Configuration;
-import java.lang.module.ModuleFinder;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.*;
-import java.util.ServiceLoader.Provider;
-import java.util.stream.Collectors;
-import javax.script.ScriptEngineFactory;
-
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeTest;
-import static org.testng.Assert.*;
-
-/**
- * Basic test for ServiceLoader. The test make use of two service providers:
- * 1. BananaScriptEngine - a ScriptEngineFactory deployed as a module on the
- * module path. It implementations a singleton via the public static
- * provider method.
- * 2. PearScriptEngine - a ScriptEngineFactory deployed on the class path
- * with a service configuration file.
- */
-
-public class Basic {
-
- // Copy the services configuration file for "pearscript" into place.
- @BeforeTest
- public void setup() throws Exception {
- Path src = Paths.get(System.getProperty("test.src", ""));
- Path classes = Paths.get(System.getProperty("test.classes", ""));
- String st = ScriptEngineFactory.class.getName();
- Path config = Paths.get("META-INF", "services", st);
- Path source = src.resolve("src").resolve("pearscript").resolve(config);
- Path target = classes.resolve(config);
- Files.createDirectories(target.getParent());
- Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
- }
-
- /**
- * Basic test of iterator() to ensure that providers located as modules
- * and on the class path are found.
- */
- @Test
- public void testIterator() {
- ServiceLoader<ScriptEngineFactory> loader
- = ServiceLoader.load(ScriptEngineFactory.class);
- Set<String> names = collectAll(loader)
- .stream()
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertTrue(names.contains("BananaScriptEngine"));
- assertTrue(names.contains("PearScriptEngine"));
- }
-
- /**
- * Basic test of iterator() to test iteration order. Providers deployed
- * as named modules should be found before providers deployed on the class
- * path.
- */
- @Test
- public void testIteratorOrder() {
- ServiceLoader<ScriptEngineFactory> loader
- = ServiceLoader.load(ScriptEngineFactory.class);
- boolean foundUnnamed = false;
- for (ScriptEngineFactory factory : collectAll(loader)) {
- if (factory.getClass().getModule().isNamed()) {
- if (foundUnnamed) {
- assertTrue(false, "Named module element after unnamed");
- }
- } else {
- foundUnnamed = true;
- }
- }
- }
-
- /**
- * Basic test of Provider::type
- */
- @Test
- public void testProviderType() {
- Set<String> types = ServiceLoader.load(ScriptEngineFactory.class)
- .stream()
- .map(Provider::type)
- .map(Class::getName)
- .collect(Collectors.toSet());
- assertTrue(types.contains("org.banana.BananaScriptEngineFactory"));
- assertTrue(types.contains("org.pear.PearScriptEngineFactory"));
- }
-
- /**
- * Basic test of Provider::get
- */
- @Test
- public void testProviderGet() {
- Set<String> names = ServiceLoader.load(ScriptEngineFactory.class)
- .stream()
- .map(Provider::get)
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertTrue(names.contains("BananaScriptEngine"));
- assertTrue(names.contains("PearScriptEngine"));
- }
-
- /**
- * Basic test of the public static provider method. BananaScriptEngine
- * defines a provider method that returns the same instance.
- */
- @Test
- public void testSingleton() {
- Optional<Provider<ScriptEngineFactory>> oprovider
- = ServiceLoader.load(ScriptEngineFactory.class)
- .stream()
- .filter(p -> p.type().getName().equals("org.banana.BananaScriptEngineFactory"))
- .findFirst();
- assertTrue(oprovider.isPresent());
- Provider<ScriptEngineFactory> provider = oprovider.get();
-
- // invoke Provider::get twice
- ScriptEngineFactory factory1 = provider.get();
- ScriptEngineFactory factory2 = provider.get();
- assertTrue(factory1 == factory2);
- }
-
- /**
- * Basic test of stream() to ensure that elements for providers in named
- * modules come before elements for providers in unnamed modules.
- */
- @Test
- public void testStreamOrder() {
- List<Class<?>> types = ServiceLoader.load(ScriptEngineFactory.class)
- .stream()
- .map(Provider::type)
- .collect(Collectors.toList());
-
- boolean foundUnnamed = false;
- for (Class<?> factoryClass : types) {
- if (factoryClass.getModule().isNamed()) {
- if (foundUnnamed) {
- assertTrue(false, "Named module element after unnamed");
- }
- } else {
- foundUnnamed = true;
- }
- }
- }
-
- /**
- * Basic test of ServiceLoader.findFirst()
- */
- @Test
- public void testFindFirst() {
- Optional<ScriptEngineFactory> ofactory
- = ServiceLoader.load(ScriptEngineFactory.class).findFirst();
- assertTrue(ofactory.isPresent());
- ScriptEngineFactory factory = ofactory.get();
- assertTrue(factory.getClass().getModule().isNamed());
-
- class S { }
- assertFalse(ServiceLoader.load(S.class).findFirst().isPresent());
- }
-
- /**
- * Basic test ServiceLoader.load specifying the platform class loader.
- * The providers on the module path and class path should not be located.
- */
- @Test
- public void testWithPlatformClassLoader() {
- ClassLoader pcl = ClassLoader.getPlatformClassLoader();
-
- // iterator
- ServiceLoader<ScriptEngineFactory> loader
- = ServiceLoader.load(ScriptEngineFactory.class, pcl);
- Set<String> names = collectAll(loader)
- .stream()
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertFalse(names.contains("BananaScriptEngine"));
- assertFalse(names.contains("PearScriptEngine"));
-
- // stream
- names = ServiceLoader.load(ScriptEngineFactory.class, pcl)
- .stream()
- .map(Provider::get)
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertFalse(names.contains("BananaScriptEngine"));
- assertFalse(names.contains("PearScriptEngine"));
- }
-
- /**
- * Basic test of ServiceLoader.load, using the class loader for
- * a module in a custom layer as the context.
- */
- @Test
- public void testWithCustomLayer1() {
- ModuleLayer layer = createCustomLayer("bananascript");
-
- ClassLoader loader = layer.findLoader("bananascript");
- List<ScriptEngineFactory> providers
- = collectAll(ServiceLoader.load(ScriptEngineFactory.class, loader));
-
- // should have at least 2 x bananascript + pearscript
- assertTrue(providers.size() >= 3);
-
- // first element should be the provider in the custom layer
- ScriptEngineFactory factory = providers.get(0);
- assertTrue(factory.getClass().getClassLoader() == loader);
- assertTrue(factory.getClass().getModule().getLayer() == layer);
- assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
-
- // remainder should be the boot layer
- providers.remove(0);
- Set<String> names = providers.stream()
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertTrue(names.contains("BananaScriptEngine"));
- assertTrue(names.contains("PearScriptEngine"));
- }
-
- /**
- * Basic test of ServiceLoader.load using a custom Layer as the context.
- */
- @Test
- public void testWithCustomLayer2() {
- ModuleLayer layer = createCustomLayer("bananascript");
-
- List<ScriptEngineFactory> factories
- = collectAll(ServiceLoader.load(layer, ScriptEngineFactory.class));
-
- // should have at least 2 x bananascript
- assertTrue(factories.size() >= 2);
-
- // first element should be the provider in the custom layer
- ScriptEngineFactory factory = factories.get(0);
- assertTrue(factory.getClass().getModule().getLayer() == layer);
- assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
-
- // remainder should be the boot layer
- factories.remove(0);
- Set<String> names = factories.stream()
- .map(ScriptEngineFactory::getEngineName)
- .collect(Collectors.toSet());
- assertTrue(names.contains("BananaScriptEngine"));
- assertFalse(names.contains("PearScriptEngine"));
- }
-
- /**
- * Basic test of ServiceLoader.load with a tree of layers.
- *
- * Test scenario:
- * - boot layer contains "bananascript", maybe other script engines
- * - layer1, with boot layer as parent, contains "bananascript"
- * - layer2, with boot layer as parent, contains "bananascript"
- * - layer3, with layer1 ad layer as parents, contains "bananascript"
- *
- * ServiceLoader should locate all 4 script engine factories in DFS order.
- */
- @Test
- public void testWithCustomLayer3() {
- ModuleLayer bootLayer = ModuleLayer.boot();
- Configuration cf0 = bootLayer.configuration();
-
- // boot layer should contain "bananascript"
- List<ScriptEngineFactory> factories
- = collectAll(ServiceLoader.load(bootLayer, ScriptEngineFactory.class));
- int countInBootLayer = factories.size();
- assertTrue(countInBootLayer >= 1);
- assertTrue(factories.stream()
- .map(p -> p.getEngineName())
- .filter("BananaScriptEngine"::equals)
- .findAny()
- .isPresent());
-
- ClassLoader scl = ClassLoader.getSystemClassLoader();
- Path dir = Paths.get(System.getProperty("test.classes", "."), "modules");
- ModuleFinder finder = ModuleFinder.of(dir);
-
- // layer1
- Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
- ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
- assertTrue(layer1.modules().size() == 1);
-
- // layer2
- Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
- ModuleLayer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
- assertTrue(layer2.modules().size() == 1);
-
- // layer3 with layer1 and layer2 as parents
- Configuration cf3 = Configuration.resolveAndBind(finder,
- List.of(cf1, cf2),
- ModuleFinder.of(),
- Set.of());
- ModuleLayer layer3
- = ModuleLayer.defineModulesWithOneLoader(cf3, List.of(layer1, layer2), scl).layer();
- assertTrue(layer3.modules().size() == 1);
-
-
- // class loaders
- ClassLoader loader1 = layer1.findLoader("bananascript");
- ClassLoader loader2 = layer2.findLoader("bananascript");
- ClassLoader loader3 = layer3.findLoader("bananascript");
- assertTrue(loader1 != loader2);
- assertTrue(loader1 != loader3);
- assertTrue(loader2 != loader3);
-
- // load all factories with layer3 as the context
- factories = collectAll(ServiceLoader.load(layer3, ScriptEngineFactory.class));
- int count = factories.size();
- assertTrue(count == countInBootLayer + 3);
-
- // the ordering should be layer3, layer1, boot layer, layer2
-
- ScriptEngineFactory factory = factories.get(0);
- assertTrue(factory.getClass().getModule().getLayer() == layer3);
- assertTrue(factory.getClass().getClassLoader() == loader3);
- assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
-
- factory = factories.get(1);
- assertTrue(factory.getClass().getModule().getLayer() == layer1);
- assertTrue(factory.getClass().getClassLoader() == loader1);
- assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
-
- // boot layer "bananascript" and maybe other factories
- int last = count -1;
- boolean found = false;
- for (int i=2; i<last; i++) {
- factory = factories.get(i);
- assertTrue(factory.getClass().getModule().getLayer() == bootLayer);
- if (factory.getEngineName().equals("BananaScriptEngine")) {
- assertFalse(found);
- found = true;
- }
- }
- assertTrue(found);
-
- factory = factories.get(last);
- assertTrue(factory.getClass().getModule().getLayer() == layer2);
- assertTrue(factory.getClass().getClassLoader() == loader2);
- assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
- }
-
-
- // -- nulls --
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testLoadNull1() {
- ServiceLoader.load(null);
- }
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testLoadNull2() {
- ServiceLoader.load((Class<?>) null, ClassLoader.getSystemClassLoader());
- }
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testLoadNull3() {
- class S { }
- ServiceLoader.load((ModuleLayer) null, S.class);
- }
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testLoadNull4() {
- ServiceLoader.load(ModuleLayer.empty(), null);
- }
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testLoadNull5() {
- ServiceLoader.loadInstalled(null);
- }
-
- /**
- * Create a custom layer by resolving the given module names. The modules
- * are located in the {@code ${test.classes}/modules} directory.
- */
- private ModuleLayer createCustomLayer(String... modules) {
- Path dir = Paths.get(System.getProperty("test.classes", "."), "modules");
- ModuleFinder finder = ModuleFinder.of(dir);
- Set<String> roots = new HashSet<>();
- Collections.addAll(roots, modules);
- ModuleLayer bootLayer = ModuleLayer.boot();
- Configuration parent = bootLayer.configuration();
- Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
- ClassLoader scl = ClassLoader.getSystemClassLoader();
- ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
- assertTrue(layer.modules().size() == 1);
- return layer;
- }
-
- private <E> List<E> collectAll(ServiceLoader<E> loader) {
- List<E> list = new ArrayList<>();
- Iterator<E> iterator = loader.iterator();
- while (iterator.hasNext()) {
- list.add(iterator.next());
- }
- return list;
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/badreturntype/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 p;
-
-/**
- * A provider factory with a provider() method with a return type that is not
- * p.Service
- */
-
-public class ProviderFactory {
- ProviderFactory() { }
-
- public static Object provider() {
- throw new RuntimeException("Should not be called");
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/classnotpublic/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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 p;
-
-/**
- * Not a provider factory because the class is not public.
- */
-
-class ProviderFactory {
- ProviderFactory() { }
-
- public static Service provider() {
- throw new RuntimeException("Should not be called");
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/classnotpublic/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/methodnotpublic/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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 p;
-
-/**
- * Not a provider factory because the static provider() method is not public.
- */
-
-public class ProviderFactory {
- ProviderFactory() { }
-
- static Service provider() {
- throw new RuntimeException("Should not be called");
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/methodnotpublic/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/returnsnull/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 p;
-
-/**
- * A provider factory that defines a public static provider method that returns
- * null.
- */
-
-public class ProviderFactory {
- ProviderFactory() { }
-
- public static Service provider() {
- return null;
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/returnsnull/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/throwsexception/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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 p;
-
-/**
- * A provider factory that throws an exception.
- */
-
-public class ProviderFactory {
- ProviderFactory() { }
-
- public static Service provider() {
- throw new RuntimeException();
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badfactories/throwsexception/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/ctornotpublic/Provider.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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 p;
-
-/**
- * A provider class with a non-public constructor
- */
-
-public class Provider implements Service {
- Provider() { }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/ctornotpublic/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/notasubtype/Provider.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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 p;
-
-/**
- * A provider class that is not a subtype of Service.
- */
-
-public class Provider {
- Provider() { }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/notpublic/Provider.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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 p;
-
-/**
- * Provider class not public.
- */
-
-class Provider implements Service {
- public Provider() { }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/notpublic/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/throwsexception/Provider.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +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 p;
-
-/**
- * A provider class with a constructor throws an exception.
- */
-
-public class Provider {
- public Provider() {
- throw new RuntimeException();
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/badproviders/throwsexception/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /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 p;
-
-public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/bananascript/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+module bananascript {
+ requires java.scripting;
+
+ provides javax.script.ScriptEngineFactory
+ with org.banana.BananaScriptEngineFactory;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/bananascript/org/banana/BananaScript.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.banana;
+
+import java.io.Reader;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+public class BananaScript implements ScriptEngine {
+
+ @Override
+ public Object eval(String script, ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader , ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(String script) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(String script, Bindings n) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object eval(Reader reader , Bindings n) {
+ throw new RuntimeException();
+ }
+ @Override
+ public void put(String key, Object value) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Object get(String key) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Bindings getBindings(int scope) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void setBindings(Bindings bindings, int scope) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public Bindings createBindings() {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptContext getContext() {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void setContext(ScriptContext context) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptEngineFactory getFactory() {
+ throw new RuntimeException();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/bananascript/org/banana/BananaScriptEngineFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.banana;
+
+import java.util.Arrays;
+import java.util.List;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+public class BananaScriptEngineFactory implements ScriptEngineFactory {
+
+ static final BananaScriptEngineFactory INSTANCE = new BananaScriptEngineFactory(null);
+
+ public BananaScriptEngineFactory() {
+ throw new RuntimeException("Should not be called");
+ }
+
+ private BananaScriptEngineFactory(Void param) { }
+
+ public static BananaScriptEngineFactory provider() {
+ return INSTANCE;
+ }
+
+ @Override
+ public String getEngineName() {
+ return "BananaScriptEngine";
+ }
+
+ @Override
+ public String getEngineVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public List<String> getExtensions() {
+ return Arrays.asList("banana");
+ }
+
+ @Override
+ public List<String> getMimeTypes() {
+ return Arrays.asList("application/x-bananascript");
+ }
+
+ @Override
+ public List<String> getNames() {
+ return Arrays.asList("BananaScript");
+ }
+
+ @Override
+ public String getLanguageName() {
+ return "BananaScript";
+ }
+
+ @Override
+ public String getLanguageVersion() {
+ return "1.0";
+ }
+
+ @Override
+ public Object getParameter(String key) {
+ return null;
+ }
+
+ @Override
+ public String getMethodCallSyntax(String obj, String m, String... args) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public String getOutputStatement(String toDisplay) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public String getProgram(String... statements) {
+ throw new RuntimeException();
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine() {
+ return new BananaScript();
+ }
+}
--- a/jdk/test/java/util/ServiceLoader/modules/modules/bananascript/module-info.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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 bananascript {
- requires java.scripting;
-
- provides javax.script.ScriptEngineFactory
- with org.banana.BananaScriptEngineFactory;
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/bananascript/org/banana/BananaScript.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.banana;
-
-import java.io.Reader;
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-
-public class BananaScript implements ScriptEngine {
-
- @Override
- public Object eval(String script, ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader , ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(String script) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(String script, Bindings n) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader , Bindings n) {
- throw new RuntimeException();
- }
- @Override
- public void put(String key, Object value) {
- throw new RuntimeException();
- }
-
- @Override
- public Object get(String key) {
- throw new RuntimeException();
- }
-
- @Override
- public Bindings getBindings(int scope) {
- throw new RuntimeException();
- }
-
- @Override
- public void setBindings(Bindings bindings, int scope) {
- throw new RuntimeException();
- }
-
- @Override
- public Bindings createBindings() {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptContext getContext() {
- throw new RuntimeException();
- }
-
- @Override
- public void setContext(ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptEngineFactory getFactory() {
- throw new RuntimeException();
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/bananascript/org/banana/BananaScriptEngineFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.banana;
-
-import java.util.Arrays;
-import java.util.List;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-
-public class BananaScriptEngineFactory implements ScriptEngineFactory {
-
- static final BananaScriptEngineFactory INSTANCE = new BananaScriptEngineFactory(null);
-
- public BananaScriptEngineFactory() {
- throw new RuntimeException("Should not be called");
- }
-
- private BananaScriptEngineFactory(Void param) { }
-
- public static BananaScriptEngineFactory provider() {
- return INSTANCE;
- }
-
- @Override
- public String getEngineName() {
- return "BananaScriptEngine";
- }
-
- @Override
- public String getEngineVersion() {
- return "1.0";
- }
-
- @Override
- public List<String> getExtensions() {
- return Arrays.asList("banana");
- }
-
- @Override
- public List<String> getMimeTypes() {
- return Arrays.asList("application/x-bananascript");
- }
-
- @Override
- public List<String> getNames() {
- return Arrays.asList("BananaScript");
- }
-
- @Override
- public String getLanguageName() {
- return "BananaScript";
- }
-
- @Override
- public String getLanguageVersion() {
- return "1.0";
- }
-
- @Override
- public Object getParameter(String key) {
- return null;
- }
-
- @Override
- public String getMethodCallSyntax(String obj, String m, String... args) {
- throw new RuntimeException();
- }
-
- @Override
- public String getOutputStatement(String toDisplay) {
- throw new RuntimeException();
- }
-
- @Override
- public String getProgram(String... statements) {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptEngine getScriptEngine() {
- return new BananaScript();
- }
-}
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test1/module-info.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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 module that provides an implementation of p.Service via a
- * provider factory class.
- */
-
-module test1 {
- exports p;
- provides p.Service with p.ProviderFactory;
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test1/p/ProviderFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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 p;
-
-/**
- * Provider factory
- */
-public class ProviderFactory {
- ProviderFactory() { }
-
- private static final Service INSTANCE = new Service() { };
-
- public static Service provider() {
- return INSTANCE;
- }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test1/p/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +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 p;
-
-/**
- * Service type
- */
-public interface Service { }
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test2/module-info.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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 module that provides an implementation of p.Service.
- */
-
-module test2 {
- exports p;
- provides p.Service with p.Provider;
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test2/p/Provider.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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 p;
-
-/**
- * Provider type
- */
-public class Provider implements Service {
- public Provider() { }
-}
-
--- a/jdk/test/java/util/ServiceLoader/modules/modules/test2/p/Service.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +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 p;
-
-/**
- * Service type
- */
-public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/p1/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+module p1 {
+ requires s1;
+ provides p.S with q.P;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/p1/q/P.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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 q;
+
+import p.S;
+
+public class P implements S { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/p2/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+module p2 {
+ requires s2;
+ provides p.S with q.P;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/p2/q/P.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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 q;
+
+import p.S;
+
+public class P implements S { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/s1/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+module s1 {
+ exports p;
+ uses p.S;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/s1/p/S.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,25 @@
+/*
+ * 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 p;
+
+public interface S { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/s2/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+module s2 {
+ exports p;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/s2/p/S.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,25 @@
+/*
+ * 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 p;
+
+public interface S { }
--- a/jdk/test/java/util/ServiceLoader/modules/src/pearscript/META-INF/services/javax.script.ScriptEngineFactory Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-org.pear.PearScriptEngineFactory
--- a/jdk/test/java/util/ServiceLoader/modules/src/pearscript/org/pear/PearScript.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.pear;
-
-import java.io.Reader;
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-
-public class PearScript implements ScriptEngine {
-
- @Override
- public Object eval(String script, ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader , ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(String script) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(String script, Bindings n) {
- throw new RuntimeException();
- }
-
- @Override
- public Object eval(Reader reader , Bindings n) {
- throw new RuntimeException();
- }
- @Override
- public void put(String key, Object value) {
- throw new RuntimeException();
- }
-
- @Override
- public Object get(String key) {
- throw new RuntimeException();
- }
-
- @Override
- public Bindings getBindings(int scope) {
- throw new RuntimeException();
- }
-
- @Override
- public void setBindings(Bindings bindings, int scope) {
- throw new RuntimeException();
- }
-
- @Override
- public Bindings createBindings() {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptContext getContext() {
- throw new RuntimeException();
- }
-
- @Override
- public void setContext(ScriptContext context) {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptEngineFactory getFactory() {
- throw new RuntimeException();
- }
-}
--- a/jdk/test/java/util/ServiceLoader/modules/src/pearscript/org/pear/PearScriptEngineFactory.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package org.pear;
-
-import java.util.Arrays;
-import java.util.List;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
-
-public class PearScriptEngineFactory implements ScriptEngineFactory {
-
- public PearScriptEngineFactory() { }
-
- public static PearScriptEngineFactory provider() {
- throw new RuntimeException("Should not be called");
- }
-
- @Override
- public String getEngineName() {
- return "PearScriptEngine";
- }
-
- @Override
- public String getEngineVersion() {
- return "1.0";
- }
-
- @Override
- public List<String> getExtensions() {
- return Arrays.asList("pear");
- }
-
- @Override
- public List<String> getMimeTypes() {
- return Arrays.asList("application/x-pearscript");
- }
-
- @Override
- public List<String> getNames() {
- return Arrays.asList("PearScript");
- }
-
- @Override
- public String getLanguageName() {
- return "PearScript";
- }
-
- @Override
- public String getLanguageVersion() {
- return "1.0";
- }
-
- @Override
- public Object getParameter(String key) {
- return null;
- }
-
- @Override
- public String getMethodCallSyntax(String obj, String m, String... args) {
- throw new RuntimeException();
- }
-
- @Override
- public String getOutputStatement(String toDisplay) {
- throw new RuntimeException();
- }
-
- @Override
- public String getProgram(String... statements) {
- throw new RuntimeException();
- }
-
- @Override
- public ScriptEngine getScriptEngine() {
- return new PearScript();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test1/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+/**
+ * Test module that provides an implementation of p.Service via a
+ * provider factory class.
+ */
+
+module test1 {
+ exports p;
+ provides p.Service with p.ProviderFactory;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test1/p/ProviderFactory.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 p;
+
+/**
+ * Provider factory
+ */
+public class ProviderFactory {
+ ProviderFactory() { }
+
+ private static final Service INSTANCE = new Service() { };
+
+ public static Service provider() {
+ return INSTANCE;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test1/p/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+/**
+ * Service type
+ */
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test2/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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 module that provides an implementation of p.Service.
+ */
+
+module test2 {
+ exports p;
+ provides p.Service with p.Provider;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test2/p/Provider.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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 p;
+
+/**
+ * Provider type
+ */
+public class Provider implements Service {
+ public Provider() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/test2/p/Service.java Fri Jun 16 09:20:39 2017 -0700
@@ -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.
+ */
+
+package p;
+
+/**
+ * Service type
+ */
+public interface Service { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/nouses/NoUsesTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * @modules java.scripting
+ * @build test/*
+ * @run main/othervm test/p.Main
+ * @summary Basic test of ServiceLoader.load from named modules that does
+ * does delcare the use
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/nouses/test/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+module test {
+ exports p;
+ requires java.scripting;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/nouses/test/p/Main.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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 p;
+
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+import javax.script.ScriptEngineFactory;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Module thisModule = Main.class.getModule();
+ assertTrue(thisModule.isNamed());
+
+ // this module does not declare that it uses ScriptEngineFactory
+ assertFalse(thisModule.canUse(ScriptEngineFactory.class));
+ try {
+ ServiceLoader.load(ScriptEngineFactory.class);
+ assertTrue(false);
+ } catch (ServiceConfigurationError expected) { }
+
+ // invoke addUses and retry
+ thisModule.addUses(ScriptEngineFactory.class);
+ ServiceLoader.load(ScriptEngineFactory.class).findFirst();
+ }
+
+ static void assertFalse(boolean value) {
+ if (value) throw new RuntimeException();
+ }
+
+ static void assertTrue(boolean value) {
+ if (!value) throw new RuntimeException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/security/SecurityTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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
+ * @build test/*
+ * @run testng/othervm test/p.Tests
+ * @summary Tests to exercise ServiceLoader with a security manager
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/security/test/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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 p.Tests.*;
+
+module test {
+ uses S1;
+ uses S2;
+ provides S1 with P1;
+ provides S2 with P2;
+ requires testng;
+ exports p to testng;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/security/test/p/Tests.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,185 @@
+/*
+ * 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 p;
+
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import static java.security.AccessController.doPrivileged;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeTest;
+import static org.testng.Assert.*;
+
+/**
+ * Basic tests with a security manager to ensure that the provider code
+ * is run with permissions restricted by whatever created the ServiceLoader
+ * object.
+ */
+
+public class Tests {
+
+ static final Permission PERM = new RuntimePermission("eatMuffin");
+
+ static <T> PrivilegedAction<ServiceLoader<T>> loadAction(Class<T> service) {
+ return () -> ServiceLoader.load(service);
+ }
+
+ static AccessControlContext withPermissions(Permission... perms) {
+ Permissions p = new Permissions();
+ for (Permission perm : perms) {
+ p.add(perm);
+ }
+ ProtectionDomain pd = new ProtectionDomain(null, p);
+ return new AccessControlContext(new ProtectionDomain[]{ pd });
+ }
+
+ static AccessControlContext noPermissions() {
+ return withPermissions(/*empty*/);
+ }
+
+ @BeforeTest
+ public void setSecurityManager() {
+ class Policy extends java.security.Policy {
+ private final Permissions perms;
+ public Policy(Permission... permissions) {
+ perms = new Permissions();
+ for (Permission permission : permissions) {
+ perms.add(permission);
+ }
+ }
+ public PermissionCollection getPermissions(CodeSource cs) {
+ return perms;
+ }
+ public PermissionCollection getPermissions(ProtectionDomain pd) {
+ return perms;
+ }
+ public boolean implies(ProtectionDomain pd, Permission p) {
+ return perms.implies(p);
+ }
+ public void refresh() { }
+ }
+ Policy policy = new Policy(new AllPermission());
+ Policy.setPolicy(policy);
+ System.setSecurityManager(new SecurityManager());
+ }
+
+ @Test
+ public void testConstructorUsingIteratorWithPermission() {
+ ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM));
+ S1 obj = sl.iterator().next();
+ }
+
+ @Test
+ public void testConstructorUsingStreamWithPermission() {
+ ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM));
+ assertTrue(sl.stream().map(Provider::get).count() == 1);
+ }
+
+ @Test
+ public void testConstructorUsingIteratorNoPermission() {
+ ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions());
+ try {
+ sl.iterator().next();
+ assertTrue(false);
+ } catch (ServiceConfigurationError e) {
+ assertTrue(e.getCause() instanceof AccessControlException);
+ }
+ }
+
+ @Test
+ public void testConstructorUsingStreamNoPermission() {
+ ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions());
+ try {
+ sl.stream().map(Provider::get).count();
+ assertTrue(false);
+ } catch (ServiceConfigurationError e) {
+ assertTrue(e.getCause() instanceof AccessControlException);
+ }
+ }
+
+ @Test
+ public void testFactoryMethodUsingIteratorWithPermission() {
+ ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM));
+ S2 obj = sl.iterator().next();
+ }
+
+ @Test
+ public void testFactoryMethodUsingStreamWithPermission() {
+ ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM));
+ assertTrue(sl.stream().map(Provider::get).count() == 1);
+ }
+
+ @Test
+ public void testFactoryMethodUsingIteratorNoPermission() {
+ ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions());
+ try {
+ sl.iterator().next();
+ assertTrue(false);
+ } catch (ServiceConfigurationError e) {
+ assertTrue(e.getCause() instanceof AccessControlException);
+ }
+ }
+
+ @Test
+ public void testFactoryMethodUsingStreamNoPermission() {
+ ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions());
+ try {
+ sl.stream().map(Provider::get).count();
+ assertTrue(false);
+ } catch (ServiceConfigurationError e) {
+ assertTrue(e.getCause() instanceof AccessControlException);
+ }
+ }
+
+
+ // service types and implementations
+
+ public static interface S1 { }
+ public static interface S2 { }
+
+ public static class P1 implements S1 {
+ public P1() {
+ AccessController.getContext().checkPermission(PERM);
+ }
+ }
+ public static class P2 implements S2 {
+ private P2() {
+ AccessController.getContext().checkPermission(PERM);
+ }
+ public static S2 provider() {
+ return new P2();
+ }
+ }
+}
--- a/jdk/test/jdk/modules/open/Basic.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/jdk/modules/open/Basic.java Fri Jun 16 09:20:39 2017 -0700
@@ -25,7 +25,7 @@
* @test
* @library modules
* @build m1/* m2/*
- * @run testng/othervm --add-modules=m1,m2 Basic
+ * @run testng/othervm --add-modules=m1,m2 --illegal-access=deny Basic
* @summary Basic test of open modules and open packages
*/
--- a/jdk/test/tools/launcher/modules/addexports/manifest/AddExportsAndOpensInManifest.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/tools/launcher/modules/addexports/manifest/AddExportsAndOpensInManifest.java Fri Jun 16 09:20:39 2017 -0700
@@ -75,7 +75,8 @@
Paths.get("Test1.class"), Paths.get("Test2.class"));
// java -jar test.jar
- return ProcessTools.executeTestJava("-jar", jarfile.toString())
+ return ProcessTools.executeTestJava("--illegal-access=deny",
+ "-jar", jarfile.toString())
.outputTo(System.out)
.errorTo(System.out);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/IllegalAccessTest.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,491 @@
+/*
+ * 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
+ * @modules java.base/jdk.internal.misc
+ * java.base/sun.security.x509
+ * java.activation
+ * @library /lib/testlibrary modules
+ * @build IllegalAccessTest TryAccess JarUtils CompilerUtils jdk.testlibrary.*
+ * @build m/*
+ * @run testng/othervm/timeout=180 IllegalAccessTest
+ * @summary Basic test for java --illegal-access=$VALUE
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.OutputAnalyzer;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test of --illegal-access=value to deny or permit access to JDK internals.
+ */
+
+@Test
+public class IllegalAccessTest {
+
+ static final String TEST_SRC = System.getProperty("test.src");
+ static final String TEST_CLASSES = System.getProperty("test.classes");
+ static final String MODULE_PATH = System.getProperty("jdk.module.path");
+
+ /**
+ * Represents the expected result of a test.
+ */
+ static final class Result {
+ private final boolean success;
+ private final List<String> expectedOutput = new ArrayList<>();
+ private final List<String> notExpectedOutput = new ArrayList<>();
+
+ Result(boolean success) {
+ this.success = success;
+ }
+
+ Result expect(String msg) {
+ expectedOutput.add(msg);
+ return this;
+ }
+
+ Result doNotExpect(String msg) {
+ notExpectedOutput.add(msg);
+ return this;
+ }
+
+ boolean shouldSucceed() {
+ return success;
+ }
+
+ Stream<String> expectedOutput() {
+ return expectedOutput.stream();
+ }
+
+ Stream<String> notExpectedOutput() {
+ return notExpectedOutput.stream();
+ }
+
+ @Override
+ public String toString() {
+ String s = (success) ? "success" : "failure";
+ for (String msg : expectedOutput) {
+ s += "/" + msg;
+ }
+ return s;
+ }
+ }
+
+ static Result success() {
+ return new Result(true);
+ }
+
+ static Result successNoWarning() {
+ return success().doNotExpect("WARNING");
+ }
+
+ static Result successWithWarning() {
+ return success().expect("WARNING");
+ }
+
+ static Result fail(String expectedOutput) {
+ return new Result(false).expect(expectedOutput).doNotExpect("WARNING");
+ }
+
+ @DataProvider(name = "denyCases")
+ public Object[][] denyCases() {
+ return new Object[][] {
+ { "accessPublicClassNonExportedPackage", fail("IllegalAccessError") },
+ { "accessPublicClassJdk9NonExportedPackage", fail("IllegalAccessError") },
+
+ { "reflectPublicMemberExportedPackage", successNoWarning() },
+ { "reflectNonPublicMemberExportedPackage", fail("IllegalAccessException") },
+ { "reflectPublicMemberNonExportedPackage", fail("IllegalAccessException") },
+ { "reflectNonPublicMemberNonExportedPackage", fail("IllegalAccessException") },
+ { "reflectPublicMemberJdk9NonExportedPackage", fail("IllegalAccessException") },
+ { "reflectPublicMemberApplicationModule", successNoWarning() },
+
+ { "setAccessiblePublicMemberExportedPackage", successNoWarning() },
+ { "setAccessibleNonPublicMemberExportedPackage", fail("InaccessibleObjectException") },
+ { "setAccessiblePublicMemberNonExportedPackage", fail("InaccessibleObjectException") },
+ { "setAccessibleNonPublicMemberNonExportedPackage", fail("InaccessibleObjectException") },
+ { "setAccessiblePublicMemberJdk9NonExportedPackage", fail("InaccessibleObjectException") },
+ { "setAccessiblePublicMemberApplicationModule", successNoWarning() },
+ { "setAccessibleNotPublicMemberApplicationModule", fail("InaccessibleObjectException") },
+
+ { "privateLookupPublicClassExportedPackage", fail("IllegalAccessException") },
+ { "privateLookupNonPublicClassExportedPackage", fail("IllegalAccessException") },
+ { "privateLookupPublicClassNonExportedPackage", fail("IllegalAccessException") },
+ { "privateLookupNonPublicClassNonExportedPackage", fail("IllegalAccessException") },
+ { "privateLookupPublicClassJdk9NonExportedPackage", fail("IllegalAccessException") },
+ };
+ }
+
+ @DataProvider(name = "permitCases")
+ public Object[][] permitCases() {
+ return new Object[][] {
+ { "accessPublicClassNonExportedPackage", successNoWarning() },
+ { "accessPublicClassJdk9NonExportedPackage", fail("IllegalAccessError") },
+
+ { "reflectPublicMemberExportedPackage", successNoWarning() },
+ { "reflectNonPublicMemberExportedPackage", fail("IllegalAccessException") },
+ { "reflectPublicMemberNonExportedPackage", successWithWarning() },
+ { "reflectNonPublicMemberNonExportedPackage", fail("IllegalAccessException") },
+ { "reflectPublicMemberJdk9NonExportedPackage", fail("IllegalAccessException") },
+
+ { "setAccessiblePublicMemberExportedPackage", successNoWarning()},
+ { "setAccessibleNonPublicMemberExportedPackage", successWithWarning() },
+ { "setAccessiblePublicMemberNonExportedPackage", successWithWarning() },
+ { "setAccessibleNonPublicMemberNonExportedPackage", successWithWarning() },
+ { "setAccessiblePublicMemberJdk9NonExportedPackage", fail("InaccessibleObjectException") },
+ { "setAccessiblePublicMemberApplicationModule", successNoWarning() },
+ { "setAccessibleNotPublicMemberApplicationModule", fail("InaccessibleObjectException") },
+
+ { "privateLookupPublicClassExportedPackage", successWithWarning() },
+ { "privateLookupNonPublicClassExportedPackage", successWithWarning() },
+ { "privateLookupPublicClassNonExportedPackage", successWithWarning() },
+ { "privateLookupNonPublicClassNonExportedPackage", successWithWarning() },
+ { "privateLookupPublicClassJdk9NonExportedPackage", fail("IllegalAccessException") },
+ { "privateLookupPublicClassApplicationModule", fail("IllegalAccessException") },
+ };
+ }
+
+ /**
+ * Checks an expected result with the output captured by the given
+ * OutputAnalyzer.
+ */
+ void checkResult(Result expectedResult, OutputAnalyzer outputAnalyzer) {
+ expectedResult.expectedOutput().forEach(outputAnalyzer::shouldContain);
+ expectedResult.notExpectedOutput().forEach(outputAnalyzer::shouldNotContain);
+ int exitValue = outputAnalyzer.getExitValue();
+ if (expectedResult.shouldSucceed()) {
+ assertTrue(exitValue == 0);
+ } else {
+ assertTrue(exitValue != 0);
+ }
+ }
+
+ /**
+ * Runs the test to execute the given test action. The VM is run with the
+ * given VM options and the output checked to see that it matches the
+ * expected result.
+ */
+ OutputAnalyzer run(String action, Result expectedResult, String... vmopts)
+ throws Exception
+ {
+ Stream<String> s1 = Stream.of(vmopts);
+ Stream<String> s2 = Stream.of("-p", MODULE_PATH, "--add-modules=m",
+ "-cp", TEST_CLASSES, "TryAccess", action);
+ String[] opts = Stream.concat(s1, s2).toArray(String[]::new);
+ OutputAnalyzer outputAnalyzer = ProcessTools
+ .executeTestJava(opts)
+ .outputTo(System.out)
+ .errorTo(System.out);
+ if (expectedResult != null)
+ checkResult(expectedResult, outputAnalyzer);
+ return outputAnalyzer;
+ }
+
+ OutputAnalyzer run(String action, String... vmopts) throws Exception {
+ return run(action, null, vmopts);
+ }
+
+ /**
+ * Runs an executable JAR to execute the given test action. The VM is run
+ * with the given VM options and the output checked to see that it matches
+ * the expected result.
+ */
+ void run(Path jarFile, String action, Result expectedResult, String... vmopts)
+ throws Exception
+ {
+ Stream<String> s1 = Stream.of(vmopts);
+ Stream<String> s2 = Stream.of("-jar", jarFile.toString(), action);
+ String[] opts = Stream.concat(s1, s2).toArray(String[]::new);
+ checkResult(expectedResult, ProcessTools.executeTestJava(opts)
+ .outputTo(System.out)
+ .errorTo(System.out));
+ }
+
+ @Test(dataProvider = "denyCases")
+ public void testDeny(String action, Result expectedResult) throws Exception {
+ run(action, expectedResult, "--illegal-access=deny");
+ }
+
+ @Test(dataProvider = "permitCases")
+ public void testDefault(String action, Result expectedResult) throws Exception {
+ run(action, expectedResult);
+ }
+
+ @Test(dataProvider = "permitCases")
+ public void testPermit(String action, Result expectedResult) throws Exception {
+ run(action, expectedResult, "--illegal-access=permit");
+ }
+
+ @Test(dataProvider = "permitCases")
+ public void testWarn(String action, Result expectedResult) throws Exception {
+ run(action, expectedResult, "--illegal-access=warn");
+ }
+
+ @Test(dataProvider = "permitCases")
+ public void testDebug(String action, Result expectedResult) throws Exception {
+ // expect stack trace with WARNING
+ if (expectedResult.expectedOutput().anyMatch("WARNING"::equals)) {
+ expectedResult.expect("TryAccess.main");
+ }
+ run(action, expectedResult, "--illegal-access=debug");
+ }
+
+ /**
+ * Test accessing internals of upgradeable module
+ */
+ public void testWithUpgradedModule() throws Exception {
+ // upgradeable module loaded from run-time image
+ run("setAccessibleNotPublicMemberUpgradeableModule", successWithWarning(),
+ "--add-modules=java.activation");
+
+ // upgradeable module loaded from upgrade module path
+ Path upgradesrc = Paths.get(TEST_SRC, "upgradesrc");
+ Path upgrademods = Files.createDirectory(Paths.get("upgrademods"));
+ Path output = upgrademods.resolve("java.activation");
+ assertTrue(CompilerUtils.compile(upgradesrc, output));
+ run("setAccessibleNotPublicMemberUpgradeableModule",
+ fail("InaccessibleObjectException"),
+ "--upgrade-module-path=" + upgrademods,
+ "--add-modules=java.activation");
+ }
+
+ /**
+ * Specify --add-exports to export a package
+ */
+ public void testWithAddExportsOption() throws Exception {
+ // warning
+ run("reflectPublicMemberNonExportedPackage", successWithWarning());
+
+ // no warning due to --add-exports
+ run("reflectPublicMemberNonExportedPackage", successNoWarning(),
+ "--add-exports", "java.base/sun.security.x509=ALL-UNNAMED");
+
+ // attempt two illegal accesses, one allowed by --add-exports
+ run("reflectPublicMemberNonExportedPackage"
+ + ",setAccessibleNonPublicMemberExportedPackage",
+ successWithWarning(),
+ "--add-exports", "java.base/sun.security.x509=ALL-UNNAMED");
+ }
+
+ /**
+ * Specify --add-open to open a package
+ */
+ public void testWithAddOpensOption() throws Exception {
+ // warning
+ run("setAccessibleNonPublicMemberExportedPackage", successWithWarning());
+
+ // no warning due to --add-opens
+ run("setAccessibleNonPublicMemberExportedPackage", successNoWarning(),
+ "--add-opens", "java.base/java.lang=ALL-UNNAMED");
+
+ // attempt two illegal accesses, one allowed by --add-opens
+ run("reflectPublicMemberNonExportedPackage"
+ + ",setAccessibleNonPublicMemberExportedPackage",
+ successWithWarning(),
+ "--add-opens", "java.base/java.lang=ALL-UNNAMED");
+ }
+
+ /**
+ * Test reflective API to export a package
+ */
+ public void testWithReflectiveExports() throws Exception {
+ // compile patch for java.base
+ Path src = Paths.get(TEST_SRC, "patchsrc", "java.base");
+ Path patch = Files.createDirectories(Paths.get("patches", "java.base"));
+ assertTrue(CompilerUtils.compile(src, patch,
+ "--patch-module", "java.base=" + src));
+
+ // reflectively export, then access
+ run("exportNonExportedPackages,reflectPublicMemberNonExportedPackage",
+ successNoWarning(),
+ "--patch-module", "java.base=" + patch);
+
+ // access, reflectively export, access again
+ List<String> output = run("reflectPublicMemberNonExportedPackage,"
+ + "exportNonExportedPackages,"
+ + "reflectPublicMemberNonExportedPackage",
+ "--patch-module", "java.base="+patch,
+ "--illegal-access=warn").asLines();
+ assertTrue(count(output, "WARNING") == 1); // one warning
+ }
+
+ /**
+ * Test reflective API to open a package
+ */
+ public void testWithReflectiveOpens() throws Exception {
+ // compile patch for java.base
+ Path src = Paths.get(TEST_SRC, "patchsrc", "java.base");
+ Path patch = Files.createDirectories(Paths.get("patches", "java.base"));
+ assertTrue(CompilerUtils.compile(src, patch,
+ "--patch-module", "java.base=" + src));
+
+ // reflectively open exported package, then access
+ run("openExportedPackage,setAccessibleNonPublicMemberExportedPackage",
+ successNoWarning(),
+ "--patch-module", "java.base=" + patch);
+
+ // access, reflectively open exported package, access again
+ List<String> output1 = run("setAccessibleNonPublicMemberExportedPackage"
+ + ",openExportedPackage"
+ + ",setAccessibleNonPublicMemberExportedPackage",
+ "--patch-module", "java.base=" + patch,
+ "--illegal-access=warn").asLines();
+ assertTrue(count(output1, "WARNING") == 1); // one warning
+
+ // reflectively open non-exported packages, then access
+ run("openNonExportedPackages,setAccessibleNonPublicMemberNonExportedPackage",
+ successNoWarning(),
+ "--patch-module", "java.base=" + patch);
+
+ // access, reflectively open non-exported package, access again
+ List<String> output2 = run("setAccessibleNonPublicMemberNonExportedPackage"
+ + ",openNonExportedPackages"
+ + ",setAccessibleNonPublicMemberNonExportedPackage",
+ "--patch-module", "java.base=" + patch,
+ "--illegal-access=warn").asLines();
+ assertTrue(count(output2, "WARNING") == 1); // one warning
+ }
+
+ /**
+ * Specify Add-Exports in JAR file manifest
+ */
+ public void testWithAddExportsInManifest() throws Exception {
+ Manifest man = new Manifest();
+ Attributes attrs = man.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ attrs.put(Attributes.Name.MAIN_CLASS, "TryAccess");
+ attrs.put(new Attributes.Name("Add-Exports"), "java.base/sun.security.x509");
+ Path jarfile = Paths.get("x.jar");
+ Path classes = Paths.get(TEST_CLASSES);
+ JarUtils.createJarFile(jarfile, man, classes, Paths.get("TryAccess.class"));
+
+ run(jarfile, "reflectPublicMemberNonExportedPackage", successNoWarning());
+
+ run(jarfile, "setAccessibleNonPublicMemberExportedPackage", successWithWarning());
+
+ // attempt two illegal accesses, one allowed by Add-Exports
+ run(jarfile, "reflectPublicMemberNonExportedPackage,"
+ + "setAccessibleNonPublicMemberExportedPackage",
+ successWithWarning());
+ }
+
+ /**
+ * Specify Add-Opens in JAR file manifest
+ */
+ public void testWithAddOpensInManifest() throws Exception {
+ Manifest man = new Manifest();
+ Attributes attrs = man.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ attrs.put(Attributes.Name.MAIN_CLASS, "TryAccess");
+ attrs.put(new Attributes.Name("Add-Opens"), "java.base/java.lang");
+ Path jarfile = Paths.get("x.jar");
+ Path classes = Paths.get(TEST_CLASSES);
+ JarUtils.createJarFile(jarfile, man, classes, Paths.get("TryAccess.class"));
+
+ run(jarfile, "setAccessibleNonPublicMemberExportedPackage", successNoWarning());
+
+ run(jarfile, "reflectPublicMemberNonExportedPackage", successWithWarning());
+
+ // attempt two illegal accesses, one allowed by Add-Opens
+ run(jarfile, "reflectPublicMemberNonExportedPackage,"
+ + "setAccessibleNonPublicMemberExportedPackage",
+ successWithWarning());
+ }
+
+ /**
+ * Test that default behavior is to print a warning on the first illegal
+ * access only.
+ */
+ public void testWarnOnFirstIllegalAccess() throws Exception {
+ String action1 = "reflectPublicMemberNonExportedPackage";
+ String action2 = "setAccessibleNonPublicMemberExportedPackage";
+ int warningCount = count(run(action1).asLines(), "WARNING");
+
+ // same illegal access
+ List<String> output1 = run(action1 + "," + action1).asLines();
+ assertTrue(count(output1, "WARNING") == warningCount);
+
+ // different illegal access
+ List<String> output2 = run(action1 + "," + action2).asLines();
+ assertTrue(count(output2, "WARNING") == warningCount);
+ }
+
+ /**
+ * Test that --illegal-access=warn prints a one-line warning per each unique
+ * illegal access.
+ */
+ public void testWarnPerIllegalAccess() throws Exception {
+ String action1 = "reflectPublicMemberNonExportedPackage";
+ String action2 = "setAccessibleNonPublicMemberExportedPackage";
+
+ // same illegal access
+ String repeatedActions = action1 + "," + action1;
+ List<String> output1 = run(repeatedActions, "--illegal-access=warn").asLines();
+ assertTrue(count(output1, "WARNING") == 1);
+
+ // different illegal access
+ String differentActions = action1 + "," + action2;
+ List<String> output2 = run(differentActions, "--illegal-access=warn").asLines();
+ assertTrue(count(output2, "WARNING") == 2);
+ }
+
+ /**
+ * Specify --illegal-access more than once, last one wins
+ */
+ public void testRepeatedOption() throws Exception {
+ run("accessPublicClassNonExportedPackage", successNoWarning(),
+ "--illegal-access=deny", "--illegal-access=permit");
+ run("accessPublicClassNonExportedPackage", fail("IllegalAccessError"),
+ "--illegal-access=permit", "--illegal-access=deny");
+ }
+
+ /**
+ * Specify bad value to --illegal-access
+ */
+ public void testBadValue() throws Exception {
+ run("accessPublicClassNonExportedPackage",
+ fail("Value specified to --illegal-access not recognized"),
+ "--illegal-access=BAD");
+ }
+
+ private int count(Iterable<String> lines, CharSequence cs) {
+ int count = 0;
+ for (String line : lines) {
+ if (line.contains(cs)) count++;
+ }
+ return count;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/TryAccess.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,194 @@
+/*
+ * 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 javax.activation.MimeTypeParameterList;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Launched by IllegalAccessTest to attempt illegal access.
+ */
+
+public class TryAccess {
+
+ public static void main(String[] args) throws Exception {
+ String[] methodNames = args[0].split(",");
+ for (String methodName : methodNames) {
+ Method m = TryAccess.class.getDeclaredMethod(methodName);
+ m.invoke(null);
+ }
+ }
+
+ // -- static access --
+
+ static void accessPublicClassNonExportedPackage() throws Exception {
+ Object obj = new sun.security.x509.X500Name("CN=name");
+ }
+
+ static void accessPublicClassJdk9NonExportedPackage() {
+ Object obj = jdk.internal.misc.Unsafe.getUnsafe();
+ }
+
+ // -- reflective access --
+
+ static void reflectPublicMemberExportedPackage() throws Exception {
+ Constructor<?> ctor = String.class.getConstructor(String.class);
+ Object name = ctor.newInstance("value");
+ }
+
+ static void reflectNonPublicMemberExportedPackage() throws Exception {
+ Field f = String.class.getDeclaredField("value");
+ Object obj = f.get("foo");
+ }
+
+ static void reflectPublicMemberNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ Constructor<?> ctor = clazz.getConstructor(String.class);
+ Object obj = ctor.newInstance("CN=user");
+ }
+
+ static void reflectNonPublicMemberNonExportedPackage() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ Field f = sc.getClass().getDeclaredField("fd");
+ Object obj = f.get(sc);
+ }
+
+ static void reflectPublicMemberJdk9NonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("jdk.internal.misc.Unsafe");
+ Method m = clazz.getMethod("getUnsafe");
+ Object obj = m.invoke(null);
+ }
+
+ static void reflectPublicMemberApplicationModule() throws Exception {
+ Class<?> clazz = Class.forName("p.Type");
+ Constructor<?> ctor = clazz.getConstructor(int.class);
+ Object obj = ctor.newInstance(1);
+ }
+
+ // -- setAccessible --
+
+ static void setAccessiblePublicMemberExportedPackage() throws Exception {
+ Constructor<?> ctor = String.class.getConstructor(String.class);
+ ctor.setAccessible(true);
+ }
+
+ static void setAccessibleNonPublicMemberExportedPackage() throws Exception {
+ Method method = ClassLoader.class.getDeclaredMethod("defineClass",
+ byte[].class, int.class, int.class);
+ method.setAccessible(true);
+ }
+
+ static void setAccessiblePublicMemberNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ Constructor<?> ctor = clazz.getConstructor(String.class);
+ ctor.setAccessible(true);
+ }
+
+ static void setAccessibleNonPublicMemberNonExportedPackage() throws Exception {
+ SocketChannel sc = SocketChannel.open();
+ Field f = sc.getClass().getDeclaredField("fd");
+ f.setAccessible(true);
+ }
+
+ static void setAccessiblePublicMemberJdk9NonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("jdk.internal.misc.Unsafe");
+ Method m = clazz.getMethod("getUnsafe");
+ m.setAccessible(true);
+ }
+
+ static void setAccessiblePublicMemberApplicationModule() throws Exception {
+ Class<?> clazz = Class.forName("p.Type");
+ Constructor<?> ctor = clazz.getConstructor(int.class);
+ ctor.setAccessible(true);
+ }
+
+ static void setAccessibleNotPublicMemberUpgradeableModule() throws Exception {
+ Method method = MimeTypeParameterList.class.getDeclaredMethod("parse",
+ String.class);
+ method.setAccessible(true);
+ }
+
+ static void setAccessibleNotPublicMemberApplicationModule() throws Exception {
+ Class<?> clazz = Class.forName("p.Type");
+ Constructor<?> ctor = clazz.getDeclaredConstructor(int.class, int.class);
+ ctor.setAccessible(true);
+ }
+
+
+ // -- privateLookupIn --
+
+ static void privateLookupPublicClassExportedPackage() throws Exception {
+ MethodHandles.privateLookupIn(String.class, MethodHandles.lookup());
+ }
+
+ static void privateLookupNonPublicClassExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("java.lang.WeakPairMap");
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ }
+
+ static void privateLookupPublicClassNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ }
+
+ static void privateLookupNonPublicClassNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.nio.ch.SocketChannelImpl");
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ }
+
+ static void privateLookupPublicClassJdk9NonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("jdk.internal.misc.Unsafe");
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ }
+
+ static void privateLookupPublicClassApplicationModule() throws Exception {
+ Class<?> clazz = Class.forName("p.Type");
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ }
+
+
+ // -- export/open packages to this unnamed module --
+
+ static void exportNonExportedPackages() throws Exception {
+ Class<?> helper = Class.forName("java.lang.Helper");
+ Method m = helper.getMethod("export", String.class, Module.class);
+ m.invoke(null, "sun.security.x509", TryAccess.class.getModule());
+ m.invoke(null, "sun.nio.ch", TryAccess.class.getModule());
+ }
+
+ static void openExportedPackage() throws Exception {
+ Class<?> helper = Class.forName("java.lang.Helper");
+ Method m = helper.getMethod("open", String.class, Module.class);
+ m.invoke(null, "java.lang", TryAccess.class.getModule());
+ }
+
+ static void openNonExportedPackages() throws Exception {
+ Class<?> helper = Class.forName("java.lang.Helper");
+ Method m = helper.getMethod("open", String.class, Module.class);
+ m.invoke(null, "sun.security.x509", TryAccess.class.getModule());
+ m.invoke(null, "sun.nio.ch", TryAccess.class.getModule());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/modules/m/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module m {
+ exports p;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/modules/m/p/Type.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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 p;
+
+public class Type {
+
+ private Type(int x, int y) { }
+
+ public Type(int x) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/patchsrc/java.base/java/lang/Helper.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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 java.lang;
+
+public class Helper {
+ private Helper() { }
+
+ /**
+ * Exports a package to a module.
+ */
+ public static void export(String pn, Module other) {
+ Helper.class.getModule().addExports(pn, other);
+ }
+
+ /**
+ * Opens a package to a module.
+ */
+ public static void open(String pn, Module other) {
+ Helper.class.getModule().addOpens(pn, other);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/upgradesrc/java.activation/javax/activation/MimeTypeParameterList.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,28 @@
+/*
+ * 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 javax.activation;
+
+public class MimeTypeParameterList {
+ protected void parse(String parameterList) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/illegalaccess/upgradesrc/java.activation/module-info.java Fri Jun 16 09:20:39 2017 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+module java.activation {
+ exports javax.activation;
+}
--- a/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java Thu Jun 15 17:24:12 2017 +0000
+++ b/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java Fri Jun 16 09:20:39 2017 -0700
@@ -23,6 +23,10 @@
package jdk.internal.module;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
/*
* Test --patch-module java.base=jdk/modules/java.base to override
* java.base with an exploded image
@@ -35,4 +39,12 @@
public static boolean hasSplitPackages() {
return true;
}
+
+ public static Map<String, Set<String>> concealedPackagesToOpen() {
+ return Collections.emptyMap();
+ }
+
+ public static Map<String, Set<String>> exportedPackagesToOpen() {
+ return Collections.emptyMap();
+ }
}
--- a/jdk/test/tools/launcher/modules/permit/AttemptAccess.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * 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.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-
-/**
- * Launched by PermitIllegalAccess to attempt illegal access.
- */
-
-public class AttemptAccess {
-
- public static void main(String[] args) throws Exception {
- String action = args[0];
- int count = Integer.parseInt(args[1]);
-
- for (int i=0; i<count; i++) {
- switch (action) {
- case "access":
- tryAccess();
- break;
- case "setAccessible":
- trySetAccessible();
- break;
- case "trySetAccessible":
- tryTrySetAccessible();
- break;
- }
- }
- }
-
- static void tryAccess() throws Exception {
- Class<?> clazz = Class.forName("sun.security.x509.X500Name");
- Constructor<?> ctor = clazz.getConstructor(String.class);
- Object name = ctor.newInstance("CN=user");
- }
-
- static void trySetAccessible() throws Exception {
- Method find = ClassLoader.class.getDeclaredMethod("findClass", String.class);
- find.setAccessible(true);
- }
-
- static void tryTrySetAccessible() throws Exception {
- Method find = ClassLoader.class.getDeclaredMethod("findClass", String.class);
- find.trySetAccessible();
- }
-
-}
--- a/jdk/test/tools/launcher/modules/permit/PermitIllegalAccess.java Thu Jun 15 17:24:12 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * 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
- * @library /lib/testlibrary
- * @build PermitIllegalAccess AttemptAccess jdk.testlibrary.*
- * @run testng PermitIllegalAccess
- * @summary Basic test for java --permit-illegal-access
- */
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Stream;
-
-import jdk.testlibrary.ProcessTools;
-import jdk.testlibrary.OutputAnalyzer;
-
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-/**
- * Basic test of --permit-illegal-access to ensure that it permits access
- * via core reflection and setAccessible/trySetAccessible.
- */
-
-@Test
-public class PermitIllegalAccess {
-
- static final String TEST_CLASSES = System.getProperty("test.classes");
- static final String TEST_MAIN = "AttemptAccess";
-
- static final String WARNING = "WARNING";
- static final String STARTUP_WARNING =
- "WARNING: --permit-illegal-access will be removed in the next major release";
- static final String ILLEGAL_ACCESS_WARNING =
- "WARNING: Illegal access by " + TEST_MAIN;
-
- /**
- * Launches AttemptAccess to execute an action, returning the OutputAnalyzer
- * to analyze the output/exitCode.
- */
- private OutputAnalyzer tryAction(String action, int count, String... args)
- throws Exception
- {
- Stream<String> s1 = Stream.of(args);
- Stream<String> s2 = Stream.of("-cp", TEST_CLASSES, TEST_MAIN, action, "" + count);
- String[] opts = Stream.concat(s1, s2).toArray(String[]::new);
- return ProcessTools.executeTestJava(opts)
- .outputTo(System.out)
- .errorTo(System.out);
- }
-
- /**
- * Launches AttemptAccess with --permit-illegal-access to execute an action,
- * returning the OutputAnalyzer to analyze the output/exitCode.
- */
- private OutputAnalyzer tryActionPermittingIllegalAccess(String action, int count)
- throws Exception
- {
- return tryAction(action, count, "--permit-illegal-access");
- }
-
- /**
- * Sanity check to ensure that IllegalAccessException is thrown.
- */
- public void testAccessFail() throws Exception {
- int exitValue = tryAction("access", 1)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("IllegalAccessException")
- .stderrShouldNotContain(WARNING)
- .stderrShouldContain("IllegalAccessException")
- .getExitValue();
- assertTrue(exitValue != 0);
- }
-
- /**
- * Sanity check to ensure that InaccessibleObjectException is thrown.
- */
- public void testSetAccessibleFail() throws Exception {
- int exitValue = tryAction("setAccessible", 1)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldNotContain(WARNING)
- .stderrShouldContain("InaccessibleObjectException")
- .getExitValue();
- assertTrue(exitValue != 0);
- }
-
- /**
- * Permit illegal access to succeed
- */
- public void testAccessPermitted() throws Exception {
- tryActionPermittingIllegalAccess("access", 1)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("IllegalAccessException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("IllegalAccessException")
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit repeated illegal access to succeed
- */
- public void testRepeatedAccessPermitted() throws Exception {
- OutputAnalyzer outputAnalyzer = tryActionPermittingIllegalAccess("access", 10)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("IllegalAccessException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("IllegalAccessException")
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);;
-
- // should only have one illegal access warning
- assertTrue(containsCount(outputAnalyzer.asLines(), ILLEGAL_ACCESS_WARNING) == 1);
- }
-
- /**
- * Permit setAccessible to succeed
- */
- public void testSetAccessiblePermitted() throws Exception {
- tryActionPermittingIllegalAccess("setAccessible", 1)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit repeated calls to setAccessible to succeed
- */
- public void testRepeatedSetAccessiblePermitted() throws Exception {
- OutputAnalyzer outputAnalyzer = tryActionPermittingIllegalAccess("setAccessible", 10)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
-
- // should only have one illegal access warning
- assertTrue(containsCount(outputAnalyzer.asLines(), ILLEGAL_ACCESS_WARNING) == 1);
- }
-
- /**
- * Permit trySetAccessible to succeed
- */
- public void testTrySetAccessiblePermitted() throws Exception {
- tryActionPermittingIllegalAccess("trySetAccessible", 1)
- .stdoutShouldNotContain(WARNING)
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit repeated calls to trySetAccessible to succeed
- */
- public void testRepeatedTrySetAccessiblePermitted() throws Exception {
- OutputAnalyzer outputAnalyzer = tryActionPermittingIllegalAccess("trySetAccessible", 10)
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
-
- // should only have one illegal access warning
- assertTrue(containsCount(outputAnalyzer.asLines(), ILLEGAL_ACCESS_WARNING) == 1);
-
- }
-
- /**
- * Permit access to succeed with --add-exports. No warning should be printed.
- */
- public void testAccessWithAddExports() throws Exception {
- tryAction("access", 1, "--add-exports", "java.base/sun.security.x509=ALL-UNNAMED")
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("IllegalAccessException")
- .stderrShouldNotContain(WARNING)
- .stderrShouldNotContain("IllegalAccessException")
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit access to succeed with --add-exports and --permit-illegal-access.
- * The only warning emitted should be the startup warning.
- */
- public void testAccessWithePermittedAddExports() throws Exception {
- tryAction("access", 1, "--permit-illegal-access",
- "--add-exports", "java.base/sun.security.x509=ALL-UNNAMED")
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("IllegalAccessException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("IllegalAccessException")
- .stderrShouldNotContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit setAccessible to succeed with --add-opens. No warning should be printed.
- */
- public void testSetAccessibleWithAddOpens() throws Exception {
- tryAction("setAccessible", 1, "--add-opens", "java.base/java.lang=ALL-UNNAMED")
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldNotContain(WARNING)
- .stderrShouldNotContain("InaccessibleObjectException")
- .shouldHaveExitValue(0);
- }
-
- /**
- * Permit setAccessible to succeed with both --add-opens and --permit-illegal-access.
- * The only warning emitted should be the startup warning.
- */
- public void testSetAccessiblePermittedWithAddOpens() throws Exception {
- tryAction("setAccessible", 1, "--permit-illegal-access",
- "--add-opens", "java.base/java.lang=ALL-UNNAMED")
- .stdoutShouldNotContain(WARNING)
- .stdoutShouldNotContain("InaccessibleObjectException")
- .stderrShouldContain(STARTUP_WARNING)
- .stderrShouldNotContain("InaccessibleObjectException")
- .stderrShouldNotContain(ILLEGAL_ACCESS_WARNING)
- .shouldHaveExitValue(0);
- }
-
-
- /**
- * Returns the number of lines in the given input that contain the
- * given char sequence.
- */
- private int containsCount(List<String> lines, CharSequence cs) {
- int count = 0;
- for (String line : lines) {
- if (line.contains(cs)) count++;
- }
- return count;
- }
-}