OpenJDK / jdk / jdk
changeset 52756:0d757a37896c
Merge
author | psadhukhan |
---|---|
date | Tue, 27 Nov 2018 10:59:24 +0530 |
parents | 40279c4862ec cecba555360c |
children | 3c4c1debe32c |
files | |
diffstat | 28 files changed, 1195 insertions(+), 193 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/adlc/adlparse.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/adlc/adlparse.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -2870,7 +2870,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); } @@ -3340,7 +3341,8 @@ const char* param = NULL; inst._parameters.reset(); while ((param = inst._parameters.iter()) != NULL) { - OperandForm* opForm = (OperandForm*) inst._localNames[param]; + OpClassForm* opForm = inst._localNames[param]->is_opclass(); + assert(opForm != NULL, "sanity"); encoding->add_parameter(opForm->_ident, param); }
--- a/src/hotspot/share/adlc/dfa.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/adlc/dfa.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -759,19 +759,27 @@ } int Expr::compute_min(const Expr *c1, const Expr *c2) { - int result = c1->_min_value + c2->_min_value; - assert( result >= 0, "Invalid cost computation"); + int v1 = c1->_min_value; + int v2 = c2->_min_value; + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + assert(v1 <= Expr::Max - v2, "Invalid cost computation"); - return result; + return v1 + v2; } + int Expr::compute_max(const Expr *c1, const Expr *c2) { - int result = c1->_max_value + c2->_max_value; - if( result < 0 ) { // check for overflow - result = Expr::Max; + int v1 = c1->_max_value; + int v2 = c2->_max_value; + + // Check for overflow without producing UB. If v2 is positive + // and not larger than Max, the subtraction cannot underflow. + assert(0 <= v2 && v2 <= Expr::Max, "sanity"); + if (v1 > Expr::Max - v2) { + return Expr::Max; } - return result; + return v1 + v2; } void Expr::print() const {
--- a/src/hotspot/share/adlc/formssel.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/adlc/formssel.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -919,7 +919,8 @@ const char *name; const char *kill_name = NULL; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); Effect* e = NULL; { @@ -936,7 +937,8 @@ // complex so simply enforce the restriction during parse. if (kill_name != NULL && e->isa(Component::TEMP) && !e->isa(Component::DEF)) { - OperandForm* kill = (OperandForm*)_localNames[kill_name]; + OpClassForm* kill = _localNames[kill_name]->is_opclass(); + assert(kill != NULL, "sanity"); globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n", _ident, kill->_ident, kill_name); } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) { @@ -2350,7 +2352,8 @@ // Add parameters that "do not appear in match rule". const char *name; for (_parameters.reset(); (name = _parameters.iter()) != NULL;) { - OperandForm *opForm = (OperandForm*)_localNames[name]; + OpClassForm *opForm = _localNames[name]->is_opclass(); + assert(opForm != NULL, "sanity"); if ( _components.operand_position(name) == -1 ) { _components.insert(name, opForm->_ident, Component::INVALID, false);
--- a/src/hotspot/share/gc/g1/dirtyCardQueue.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/gc/g1/dirtyCardQueue.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -221,23 +221,22 @@ BufferNode* DirtyCardQueueSet::get_completed_buffer(size_t stop_at) { - BufferNode* nd = NULL; MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); if (_n_completed_buffers <= stop_at) { - _process_completed = false; return NULL; } - if (_completed_buffers_head != NULL) { - nd = _completed_buffers_head; - assert(_n_completed_buffers > 0, "Invariant"); - _completed_buffers_head = nd->next(); - _n_completed_buffers--; - if (_completed_buffers_head == NULL) { - assert(_n_completed_buffers == 0, "Invariant"); - _completed_buffers_tail = NULL; - } + assert(_n_completed_buffers > 0, "invariant"); + assert(_completed_buffers_head != NULL, "invariant"); + assert(_completed_buffers_tail != NULL, "invariant"); + + BufferNode* nd = _completed_buffers_head; + _completed_buffers_head = nd->next(); + _n_completed_buffers--; + if (_completed_buffers_head == NULL) { + assert(_n_completed_buffers == 0, "Invariant"); + _completed_buffers_tail = NULL; } DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked()); return nd;
--- a/src/hotspot/share/gc/shared/ptrQueue.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/gc/shared/ptrQueue.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -327,7 +327,7 @@ void PtrQueueSet::notify_if_necessary() { MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag); - assert(_process_completed_threshold >= 0, "_process_completed is negative"); + assert(_process_completed_threshold >= 0, "_process_completed_threshold is negative"); if (_n_completed_buffers >= (size_t)_process_completed_threshold || _max_completed_queue == 0) { _process_completed = true; if (_notify_when_complete)
--- a/src/hotspot/share/memory/heapShared.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/memory/heapShared.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -441,11 +441,6 @@ // during VM initialization time. No lock is needed. if (record != NULL) { Thread* THREAD = Thread::current(); - if (log_is_enabled(Info, cds, heap)) { - ResourceMark rm; - log_info(cds, heap)("initialize_from_archived_subgraph " PTR_FORMAT " %s", p2i(k), - k->external_name()); - } int i; // Load/link/initialize the klasses of the objects in the subgraph. @@ -511,8 +506,13 @@ log_debug(cds, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v)); } - // Done. Java code can see the archived sub-graphs referenced from k's - // mirror after this point. + // Done. Java code can see the archived sub-graphs referenced from k's + // mirror after this point. + if (log_is_enabled(Info, cds, heap)) { + ResourceMark rm; + log_info(cds, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT, + k->external_name(), p2i(k)); + } } } }
--- a/src/hotspot/share/utilities/hashtable.cpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/utilities/hashtable.cpp Tue Nov 27 10:59:24 2018 +0530 @@ -107,36 +107,6 @@ } } -template <MEMFLAGS F> void BasicHashtable<F>::BucketUnlinkContext::free_entry(BasicHashtableEntry<F>* entry) { - entry->set_next(_removed_head); - _removed_head = entry; - if (_removed_tail == NULL) { - _removed_tail = entry; - } - _num_removed++; -} - -template <MEMFLAGS F> void BasicHashtable<F>::bulk_free_entries(BucketUnlinkContext* context) { - if (context->_num_removed == 0) { - assert(context->_removed_head == NULL && context->_removed_tail == NULL, - "Zero entries in the unlink context, but elements linked from " PTR_FORMAT " to " PTR_FORMAT, - p2i(context->_removed_head), p2i(context->_removed_tail)); - return; - } - - // MT-safe add of the list of BasicHashTableEntrys from the context to the free list. - BasicHashtableEntry<F>* current = _free_list; - while (true) { - context->_removed_tail->set_next(current); - BasicHashtableEntry<F>* old = Atomic::cmpxchg(context->_removed_head, &_free_list, current); - if (old == current) { - break; - } - current = old; - } - Atomic::add(-context->_num_removed, &_number_of_entries); -} - // For oops and Strings the size of the literal is interesting. For other types, nobody cares. static int literal_size(ConstantPool*) { return 0; } static int literal_size(Klass*) { return 0; }
--- a/src/hotspot/share/utilities/hashtable.hpp Tue Nov 27 10:45:54 2018 +0530 +++ b/src/hotspot/share/utilities/hashtable.hpp Tue Nov 27 10:59:24 2018 +0530 @@ -204,25 +204,6 @@ // Free the buckets in this hashtable void free_buckets(); - - // Helper data structure containing context for the bucket entry unlink process, - // storing the unlinked buckets in a linked list. - // Also avoids the need to pass around these four members as parameters everywhere. - struct BucketUnlinkContext { - int _num_processed; - int _num_removed; - // Head and tail pointers for the linked list of removed entries. - BasicHashtableEntry<F>* _removed_head; - BasicHashtableEntry<F>* _removed_tail; - - BucketUnlinkContext() : _num_processed(0), _num_removed(0), _removed_head(NULL), _removed_tail(NULL) { - } - - void free_entry(BasicHashtableEntry<F>* entry); - }; - // Add of bucket entries linked together in the given context to the global free list. This method - // is mt-safe wrt. to other calls of this method. - void bulk_free_entries(BucketUnlinkContext* context); public: int table_size() const { return _table_size; } void set_entry(int index, BasicHashtableEntry<F>* entry);
--- a/src/java.base/share/classes/java/lang/String.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/java.base/share/classes/java/lang/String.java Tue Nov 27 10:59:24 2018 +0530 @@ -37,6 +37,7 @@ import java.util.Objects; import java.util.Spliterator; import java.util.StringJoiner; +import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -2973,6 +2974,25 @@ } /** + * This method allows the application of a function to {@code this} + * string. The function should expect a single String argument + * and produce an {@code R} result. + * + * @param f functional interface to a apply + * + * @param <R> class of the result + * + * @return the result of applying the function to this string + * + * @see java.util.function.Function + * + * @since 12 + */ + public <R> R transform(Function<? super String, ? extends R> f) { + return f.apply(this); + } + + /** * This object (which is already a string!) is itself returned. * * @return the string itself.
--- a/src/java.base/share/classes/java/security/KeyStore.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/java.base/share/classes/java/security/KeyStore.java Tue Nov 27 10:59:24 2018 +0530 @@ -1813,8 +1813,8 @@ } } - throw new KeyStoreException("Unrecognized keystore format: " + - keystore); + throw new KeyStoreException("This keystore does not support probing " + + "and must be loaded with a specified type"); } /**
--- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java Tue Nov 27 10:59:24 2018 +0530 @@ -530,22 +530,22 @@ ProtocolVersion protocolVersion, SecretKey key, IvParameterSpec iv, SecureRandom random) throws GeneralSecurityException { - if (readCipherGenerators.length == 0) { + if (writeCipherGenerators.length == 0) { return null; } - WriteCipherGenerator rcg = null; + WriteCipherGenerator wcg = null; for (Map.Entry<WriteCipherGenerator, ProtocolVersion[]> me : writeCipherGenerators) { for (ProtocolVersion pv : me.getValue()) { if (protocolVersion == pv) { - rcg = me.getKey(); + wcg = me.getKey(); } } } - if (rcg != null) { - return rcg.createCipher(this, authenticator, + if (wcg != null) { + return wcg.createCipher(this, authenticator, protocolVersion, transformation, key, iv, random); } return null;
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Tue Nov 27 10:59:24 2018 +0530 @@ -1328,28 +1328,39 @@ if (f.exists()) { // Probe for real type. A JKS can be loaded as PKCS12 because // DualFormat support, vice versa. - keyStore = KeyStore.getInstance(f, pass); - String realType = keyStore.getType(); - if (realType.equalsIgnoreCase("JKS") - || realType.equalsIgnoreCase("JCEKS")) { - boolean allCerts = true; - for (String a : Collections.list(keyStore.aliases())) { - if (!keyStore.entryInstanceOf( - a, TrustedCertificateEntry.class)) { - allCerts = false; - break; + String realType = storetype; + try { + keyStore = KeyStore.getInstance(f, pass); + realType = keyStore.getType(); + if (realType.equalsIgnoreCase("JKS") + || realType.equalsIgnoreCase("JCEKS")) { + boolean allCerts = true; + for (String a : Collections.list(keyStore.aliases())) { + if (!keyStore.entryInstanceOf( + a, TrustedCertificateEntry.class)) { + allCerts = false; + break; + } + } + // Don't warn for "cacerts" style keystore. + if (!allCerts) { + weakWarnings.add(String.format( + rb.getString("jks.storetype.warning"), + realType, ksfname)); } } - // Don't warn for "cacerts" style keystore. - if (!allCerts) { - weakWarnings.add(String.format( - rb.getString("jks.storetype.warning"), - realType, ksfname)); - } + } catch (KeyStoreException e) { + // Probing not supported, therefore cannot be JKS or JCEKS. + // Skip the legacy type warning at all. } if (inplaceImport) { - String realSourceStoreType = KeyStore.getInstance( - new File(inplaceBackupName), srcstorePass).getType(); + String realSourceStoreType = srcstoretype; + try { + realSourceStoreType = KeyStore.getInstance( + new File(inplaceBackupName), srcstorePass).getType(); + } catch (KeyStoreException e) { + // Probing not supported. Assuming srcstoretype. + } String format = realType.equalsIgnoreCase(realSourceStoreType) ? rb.getString("backup.keystore.warning") :
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Nov 27 10:59:24 2018 +0530 @@ -1778,9 +1778,6 @@ if (condTypes.isEmpty()) { return syms.objectType; //TODO: how to handle? } - if (condTypes.size() == 1) { - return condTypes.head; - } Type first = condTypes.head; // If same type, that is the result if (condTypes.tail.stream().allMatch(t -> types.isSameType(first, t)))
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java Tue Nov 27 10:59:24 2018 +0530 @@ -169,7 +169,7 @@ DocPath dfilePath = dstPath.resolve(srcfile.getName()); HtmlDocletWriter docletWriter = new DocFileWriter(configuration, dfilePath, element); - configuration.messages.notice("doclet.Generating_0", docletWriter.filename); + configuration.messages.notice("doclet.Generating_0", docletWriter.filename.getPath()); String title = getWindowTitle(docletWriter, dfElement).trim(); HtmlTree htmlContent = docletWriter.getBody(true, title);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java Tue Nov 27 10:59:24 2018 +0530 @@ -139,19 +139,6 @@ if (configuration.createtree) { TreeWriter.generate(configuration, classtree); } - if (configuration.createindex) { - configuration.buildSearchTagIndex(); - if (configuration.splitindex) { - SplitIndexWriter.generate(configuration, indexbuilder); - } else { - SingleIndexWriter.generate(configuration, indexbuilder); - } - AllClassesIndexWriter.generate(configuration, - new IndexBuilder(configuration, nodeprecated, true)); - if (!configuration.packages.isEmpty()) { - AllPackagesIndexWriter.generate(configuration); - } - } if (!(configuration.nodeprecatedlist || nodeprecated)) { DeprecatedListWriter.generate(configuration); @@ -172,6 +159,20 @@ } } + if (configuration.createindex) { + configuration.buildSearchTagIndex(); + if (configuration.splitindex) { + SplitIndexWriter.generate(configuration, indexbuilder); + } else { + SingleIndexWriter.generate(configuration, indexbuilder); + } + AllClassesIndexWriter.generate(configuration, + new IndexBuilder(configuration, nodeprecated, true)); + if (!configuration.packages.isEmpty()) { + AllPackagesIndexWriter.generate(configuration); + } + } + if (!configuration.frames) { if (configuration.createoverview) { IndexRedirectWriter.generate(configuration, DocPaths.OVERVIEW_SUMMARY, DocPaths.INDEX);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Tue Nov 27 10:59:24 2018 +0530 @@ -41,11 +41,11 @@ import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; -import jdk.javadoc.internal.doclets.formats.html.markup.Links; import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml; import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.Content; +import jdk.javadoc.internal.doclets.toolkit.DocletElement; import jdk.javadoc.internal.doclets.toolkit.Resources; import jdk.javadoc.internal.doclets.toolkit.builders.SerializedFormBuilder; import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter; @@ -421,42 +421,38 @@ SearchIndexItem si = new SearchIndexItem(); si.setLabel(tagText); si.setDescription(desc); + si.setUrl(htmlWriter.path.getPath() + "#" + anchorName); DocPaths docPaths = configuration.docPaths; new SimpleElementVisitor9<Void, Void>() { @Override - public Void visitModule(ModuleElement e, Void p) { - si.setUrl(docPaths.moduleSummary(e).getPath() + "#" + anchorName); - si.setHolder(utils.getFullyQualifiedName(element)); - return null; - } - - @Override - public Void visitPackage(PackageElement e, Void p) { - si.setUrl(docPaths.forPackage(e).getPath() - + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName); - si.setHolder(utils.getSimpleName(element)); - return null; - } - - @Override - public Void visitType(TypeElement e, Void p) { - si.setUrl(docPaths.forClass(e).getPath() + "#" + anchorName); - si.setHolder(utils.getFullyQualifiedName(e)); - return null; - } - - @Override public Void visitVariable(VariableElement e, Void p) { TypeElement te = utils.getEnclosingTypeElement(e); - si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName); si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e)); return null; } @Override + public Void visitUnknown(Element e, Void p) { + if (e instanceof DocletElement) { + DocletElement de = (DocletElement) e; + switch (de.getSubKind()) { + case OVERVIEW: + si.setHolder(resources.getText("doclet.Overview")); + break; + case DOCFILE: + si.setHolder(de.getPackageElement().toString()); + break; + default: + throw new IllegalStateException(); + } + return null; + } else { + return super.visitUnknown(e, p); + } + } + + @Override protected Void defaultAction(Element e, Void p) { - TypeElement te = utils.getEnclosingTypeElement(e); - si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName); si.setHolder(utils.getFullyQualifiedName(e)); return null; }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Tue Nov 27 10:59:24 2018 +0530 @@ -230,6 +230,7 @@ but the packages defined in {0} are in named modules. doclet.linkMismatch_ModuleLinkedtoPackage=The code being documented uses modules but the packages defined \ in {0} are in the unnamed module. +doclet.urlRedirected=URL {0} was redirected to {1} -- Update the command-line options to suppress this warning. #Documentation for Enums doclet.enum_values_doc.fullbody=\
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java Tue Nov 27 10:45:54 2018 +0530 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java Tue Nov 27 10:59:24 2018 +0530 @@ -25,8 +25,15 @@ package jdk.javadoc.internal.doclets.toolkit.util; -import java.io.*; -import java.net.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; @@ -35,6 +42,7 @@ import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.tools.Diagnostic; +import javax.tools.Diagnostic.Kind; import javax.tools.DocumentationTool; import jdk.javadoc.doclet.Reporter; @@ -85,7 +93,7 @@ private class Item { /** - * Element name, found in the "element-list" file in the {@link path}. + * Element name, found in the "element-list" file in the {@link #path}. */ final String elementName; @@ -157,7 +165,7 @@ */ public boolean isModule(String elementName) { Item elem = moduleItems.get(elementName); - return (elem == null) ? false : true; + return elem != null; } /** @@ -245,14 +253,6 @@ } } - private URL toURL(String url) throws Fault { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new Fault(resources.getText("doclet.MalformedURL", url), e); - } - } - private class Fault extends Exception { private static final long serialVersionUID = 0; @@ -296,7 +296,9 @@ private void readElementListFromURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.ELEMENT_LIST.getPath()).toURL(); - readElementList(link.openStream(), urlpath, false); + try (InputStream in = open(link)) { + readElementList(in, urlpath, false); + } } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(resources.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -313,7 +315,9 @@ private void readAlternateURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.PACKAGE_LIST.getPath()).toURL(); - readElementList(link.openStream(), urlpath, false); + try (InputStream in = open(link)) { + readElementList(in, urlpath, false); + } } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(resources.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -377,9 +381,9 @@ private void readElementList(InputStream input, String path, boolean relative) throws Fault, IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(input))) { - String elemname = null; + String elemname; + DocPath elempath; String moduleName = null; - DocPath elempath = null; DocPath basePath = DocPath.create(path); while ((elemname = in.readLine()) != null) { if (elemname.length() > 0) { @@ -406,9 +410,25 @@ } } + private void checkLinkCompatibility(String packageName, String moduleName, String path) throws Fault { + PackageElement pe = utils.elementUtils.getPackageElement(packageName); + if (pe != null) { + ModuleElement me = (ModuleElement)pe.getEnclosingElement(); + if (me == null || me.isUnnamed()) { + if (moduleName != null) { + throw new Fault(resources.getText("doclet.linkMismatch_PackagedLinkedtoModule", + path), null); + } + } else if (moduleName == null) { + throw new Fault(resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage", + path), null); + } + } + } + public boolean isUrl (String urlCandidate) { try { - URL ignore = new URL(urlCandidate); + new URL(urlCandidate); //No exception was thrown, so this must really be a URL. return true; } catch (MalformedURLException e) { @@ -417,17 +437,70 @@ } } - private void checkLinkCompatibility(String packageName, String moduleName, String path) throws Fault { - PackageElement pe = configuration.utils.elementUtils.getPackageElement(packageName); - if (pe != null) { - ModuleElement me = (ModuleElement)pe.getEnclosingElement(); - if (me == null || me.isUnnamed()) { - if (moduleName != null) - throw new Fault(resources.getText("doclet.linkMismatch_PackagedLinkedtoModule", - path), null); - } else if (moduleName == null) - throw new Fault(resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage", - path), null); + private URL toURL(String url) throws Fault { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new Fault(resources.getText("doclet.MalformedURL", url), e); } } + + /** + * Open a stream to a URL, following a limited number of redirects + * if necessary. + * + * @param url the URL + * @return the stream + * @throws IOException if an error occurred accessing the URL + */ + private InputStream open(URL url) throws IOException { + URLConnection conn = url.openConnection(); + + boolean redir; + int redirects = 0; + InputStream in; + + do { + // Open the input stream before getting headers, + // because getHeaderField() et al swallow IOExceptions. + in = conn.getInputStream(); + redir = false; + + if (conn instanceof HttpURLConnection) { + HttpURLConnection http = (HttpURLConnection)conn; + int stat = http.getResponseCode(); + // See: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + // https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection + switch (stat) { + case 300: // Multiple Choices + case 301: // Moved Permanently + case 302: // Found (previously Moved Temporarily) + case 303: // See Other + case 307: // Temporary Redirect + case 308: // Permanent Redirect + URL base = http.getURL(); + String loc = http.getHeaderField("Location"); + URL target = null; + if (loc != null) { + target = new URL(base, loc); + } + http.disconnect(); + if (target == null || redirects >= 5) { + throw new IOException("illegal URL redirect"); + } + redir = true; + conn = target.openConnection(); + redirects++; + } + } + } while (redir); + + if (!url.equals(conn.getURL())) { + configuration.getReporter().print(Kind.WARNING, + resources.getText("doclet.urlRedirected", url, conn.getURL())); + } + + return in; + } }
--- a/test/hotspot/jtreg/compiler/arguments/TestScavengeRootsInCode.java Tue Nov 27 10:45:54 2018 +0530 +++ b/test/hotspot/jtreg/compiler/arguments/TestScavengeRootsInCode.java Tue Nov 27 10:59:24 2018 +0530 @@ -25,7 +25,7 @@ * @test * @bug 8214025 * @summary Test compilation with non-default value for ScavengeRootsInCode. - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xcomp -XX:-TieredCompilation * -XX:ScavengeRootsInCode=1 compiler.arguments.TestScavengeRootsInCode */
--- a/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java Tue Nov 27 10:45:54 2018 +0530 +++ b/test/hotspot/jtreg/runtime/NMT/MallocStressTest.java Tue Nov 27 10:59:24 2018 +0530 @@ -186,13 +186,19 @@ if (size == 0) size = 1; long addr = MallocStressTest.whiteBox.NMTMallocWithPseudoStack(size, r); if (addr != 0) { - MallocMemory mem = new MallocMemory(addr, size); - synchronized(MallocStressTest.mallocd_memory) { - MallocStressTest.mallocd_memory.add(mem); - MallocStressTest.mallocd_total += size; + try { + MallocMemory mem = new MallocMemory(addr, size); + synchronized(MallocStressTest.mallocd_memory) { + MallocStressTest.mallocd_memory.add(mem); + MallocStressTest.mallocd_total += size; + } + } catch (OutOfMemoryError e) { + // Don't include this malloc memory because it didn't + // get recorded in mallocd_memory list. + MallocStressTest.whiteBox.NMTFree(addr); + break; } } else { - System.out.println("Out of malloc memory"); break; } }
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/ReplaceCriticalClasses.java Tue Nov 27 10:45:54 2018 +0530 +++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/ReplaceCriticalClasses.java Tue Nov 27 10:59:24 2018 +0530 @@ -41,8 +41,13 @@ public class ReplaceCriticalClasses { public static void main(String args[]) throws Throwable { + ReplaceCriticalClasses rcc = new ReplaceCriticalClasses(); + rcc.process(args); + } + + public void process(String args[]) throws Throwable { if (args.length == 0) { - launchChildProcesses(); + launchChildProcesses(getTests()); } else if (args.length == 3 && args[0].equals("child")) { Class klass = Class.forName(args[2].replace("/", ".")); if (args[1].equals("-shared")) { @@ -58,7 +63,7 @@ } } - static void launchChildProcesses() throws Throwable { + public String[] getTests() { String tests[] = { // CDS should be disabled -- these critical classes will be replaced // because JvmtiExport::early_class_hook_env() is true. @@ -74,18 +79,25 @@ "java/lang/Cloneable", "java/io/Serializable", - // Try to replace classes that are used by the archived subgraph graphs. - "-subgraph java/util/ArrayList", - "-subgraph java/lang/module/ResolvedModule", + /* Try to replace classes that are used by the archived subgraph graphs. + The following test cases are in ReplaceCriticalClassesForSubgraphs.java. + "-early -notshared -subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph", + "-early -notshared -subgraph java/lang/Long java.lang.Long$LongCache", + "-subgraph java/lang/Long java.lang.Long$LongCache", + */ - // Replace classes that are loaded after JVMTI_PHASE_PRIMORDIAL. It's OK to replace such + // Replace classes that are loaded after JVMTI_PHASE_PRIMORDIAL. It's OK to replace + // such // classes even when CDS is enabled. Nothing bad should happen. "-notshared jdk/internal/vm/PostVMInitHook", "-notshared java/util/Locale", "-notshared sun/util/locale/BaseLocale", "-notshared java/lang/Readable", }; + return tests; + } + static void launchChildProcesses(String tests[]) throws Throwable { int n = 0; for (String s : tests) { System.out.println("Test case[" + (n++) + "] = \"" + s + "\""); @@ -96,9 +108,10 @@ static void launchChild(String args[]) throws Throwable { if (args.length < 1) { - throw new RuntimeException("Invalid test case. Should be <-early> <-subgraph> <-notshared> klassName"); + throw new RuntimeException("Invalid test case. Should be <-early> <-subgraph> <-notshared> klassName subgraphKlass"); } String klassName = null; + String subgraphKlass = null; String early = ""; boolean subgraph = false; String shared = "-shared"; @@ -112,11 +125,19 @@ } else if (opt.equals("-notshared")) { shared = opt; } else { + if (!subgraph) { throw new RuntimeException("Unknown option: " + opt); + } } } - klassName = args[args.length-1]; + if (subgraph) { + klassName = args[args.length-2]; + subgraphKlass = args[args.length-1]; + } else { + klassName = args[args.length-1]; + } Class.forName(klassName.replace("/", ".")); // make sure it's a valid class + final String subgraphInit = "initialize_from_archived_subgraph " + subgraphKlass; // We will pass an option like "-agentlib:SimpleClassFileLoadHook=java/util/Locale,XXX,XXX". // The SimpleClassFileLoadHook agent would attempt to hook the java/util/Locale class @@ -142,8 +163,7 @@ "-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar")); if (subgraph) { - opts.addSuffix("-Xlog:cds+heap", - "-Xlog:class+load"); + opts.addSuffix("-Xlog:cds,cds+heap"); } opts.addSuffix("ReplaceCriticalClasses", @@ -152,11 +172,22 @@ klassName); final boolean expectDisable = !early.equals(""); + final boolean checkSubgraph = subgraph; + final boolean expectShared = shared.equals("-shared"); CDSTestUtils.run(opts).assertNormalExit(out -> { if (expectDisable) { out.shouldContain("UseSharedSpaces: CDS is disabled because early JVMTI ClassFileLoadHook is in use."); System.out.println("CDS disabled as expected"); } + if (checkSubgraph) { + if (expectShared) { + if (!out.getOutput().contains("UseSharedSpaces: Unable to map at required address in java heap")) { + out.shouldContain(subgraphInit); + } + } else { + out.shouldNotContain(subgraphInit); + } + } }); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/ReplaceCriticalClassesForSubgraphs.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary Tests how CDS works when critical library classes are replaced with JVMTI ClassFileLoadHook + * @library /test/lib + * @requires vm.cds.archived.java.heap + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox + * @run main/othervm/native ReplaceCriticalClassesForSubgraphs + */ + +public class ReplaceCriticalClassesForSubgraphs extends ReplaceCriticalClasses { + public static void main(String args[]) throws Throwable { + ReplaceCriticalClassesForSubgraphs rcc = new ReplaceCriticalClassesForSubgraphs(); + rcc.process(args); + } + + public String[] getTests() { + String tests[] = { + // Try to replace classes that are used by the archived subgraph graphs. + "-early -notshared -subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph", + "-early -notshared -subgraph java/lang/Long java.lang.Long$LongCache", + "-subgraph java/lang/Long java.lang.Long$LongCache", + }; + return tests; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/String/Transform.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Unit tests for String#transform(Function<String, R> f) + * @run main Transform + */ + +import java.util.function.Function; +import java.util.stream.Collectors; + +public class Transform { + public static void main(String[] args) { + test1(); + } + + /* + * Test String#transform(Function<? super String, ? extends R> f) functionality. + */ + static void test1() { + simpleTransform("toUpperCase", "abc", s -> s.toUpperCase()); + simpleTransform("toLowerCase", "ABC", s -> s.toLowerCase()); + simpleTransform("substring", "John Smith", s -> s.substring(0, 4)); + + String multiline = " This is line one\n" + + " This is line two\n" + + " This is line three\n"; + String expected = "This is line one!\n" + + " This is line two!\n" + + " This is line three!\n"; + check("multiline", multiline.transform(string -> { + return string.lines() + .map(s -> s.transform(t -> t.substring(4) + "!")) + .collect(Collectors.joining("\n", "", "\n")); + }), expected); + } + + static void simpleTransform(String test, String s, Function<String, String> f) { + check(test, s.transform(f), f.apply(s)); + } + + static void check(String test, Object output, Object expected) { + if (output != expected && (output == null || !output.equals(expected))) { + System.err.println("Testing " + test + ": unexpected result"); + System.err.println("Output:"); + System.err.println(output); + System.err.println("Expected:"); + System.err.println(expected); + throw new RuntimeException(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/security/tools/keytool/ProbingFailure.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8214100 + * @summary use of keystore probing results in unnecessary exception thrown + * @library /test/lib + * @compile -XDignore.symbol.file ProbingFailure.java + * @run main ProbingFailure + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.KeyStoreSpi; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.util.Date; +import java.util.Enumeration; + +public class ProbingFailure { + + public static void main(String[] args) throws Exception { + + // genkeypair + kt("-genkeypair -keystore mks -alias a -dname CN=A -storetype MYKS") + .shouldHaveExitValue(0); + + // list + kt("-list -keystore mks -storetype MYKS") + .shouldHaveExitValue(0); + + kt("-list -keystore mks") + .shouldHaveExitValue(1) + .shouldContain("This keystore does not support probing"); + + // importkeystore + kt("-importkeystore -srckeystore mks -srcstoretype MYKS -destkeystore p12") + .shouldHaveExitValue(0); + + kt("-importkeystore -srckeystore mks -destkeystore p12a") + .shouldHaveExitValue(1) + .shouldContain("This keystore does not support probing"); + + // in-place importkeystore + kt("-importkeystore -srckeystore mks -srcstoretype MYKS -destkeystore mks -deststoretype myks") + .shouldContain("The original keystore \"mks\" is backed up") + .shouldHaveExitValue(0); + + kt("-importkeystore -srckeystore mks -srcstoretype MYKS -destkeystore mks") + .shouldContain("Migrated \"mks\" to PKCS12") + .shouldHaveExitValue(0); + + kt("-importkeystore -srckeystore p12 -destkeystore p12 -deststoretype MYKS") + .shouldContain("Migrated \"p12\" to MYKS") + .shouldHaveExitValue(0); + } + + static OutputAnalyzer kt(String cmd) throws Exception { + return SecurityTools.keytool( + "-storepass changeit -keypass changeit -debug " + + "-srcstorepass changeit -deststorepass changeit " + + "-providerclass ProbingFailure$MyProvider " + + "-providerpath " + System.getProperty("test.classes") + + " " + cmd); + } + + public static class MyProvider extends Provider { + public MyProvider() { + super("MP", "1.0", "My Provider"); + put("KeyStore.MYKS", "ProbingFailure$MyKS"); + } + } + + // The MYKS keystore prepends a zero byte before a PKCS12 file + // and does not support probing. + public static class MyKS extends KeyStoreSpi { + + KeyStore ks; + + public MyKS() { + try { + ks = KeyStore.getInstance("PKCS12"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public Key engineGetKey(String alias, char[] password) + throws NoSuchAlgorithmException, UnrecoverableKeyException { + try { + return ks.getKey(alias, password); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public Certificate[] engineGetCertificateChain(String alias) { + try { + return ks.getCertificateChain(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public Certificate engineGetCertificate(String alias) { + try { + return ks.getCertificate(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public Date engineGetCreationDate(String alias) { + try { + return ks.getCreationDate(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public void engineSetKeyEntry(String alias, Key key, char[] password, + Certificate[] chain) throws KeyStoreException { + ks.setKeyEntry(alias, key, password, chain); + } + + @Override + public void engineSetKeyEntry(String alias, byte[] key, + Certificate[] chain) throws KeyStoreException { + ks.setKeyEntry(alias, key, chain); + } + + @Override + public void engineSetCertificateEntry(String alias, Certificate cert) + throws KeyStoreException { + ks.setCertificateEntry(alias, cert); + } + + @Override + public void engineDeleteEntry(String alias) throws KeyStoreException { + ks.deleteEntry(alias); + } + + @Override + public Enumeration<String> engineAliases() { + try { + return ks.aliases(); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean engineContainsAlias(String alias) { + try { + return ks.containsAlias(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public int engineSize() { + try { + return ks.size(); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean engineIsKeyEntry(String alias) { + try { + return ks.isKeyEntry(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean engineIsCertificateEntry(String alias) { + try { + return ks.isCertificateEntry(alias); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public String engineGetCertificateAlias(Certificate cert) { + try { + return ks.getCertificateAlias(cert); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public void engineStore(OutputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException { + stream.write(0); + try { + ks.store(stream, password); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public void engineLoad(InputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException { + if (stream != null) { + stream.read(); + } + ks.load(stream, password); + } + + @Override + public boolean engineProbe(InputStream stream) { + return false; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8213957 8213958 + * @summary Test use of at-index in package-iinfo and doc-files + * @library /tools/lib ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox JavadocTester + * @run main TestIndexInPackageFiles + */ + +import java.io.IOException; +import java.nio.file.Path; +import toolbox.ToolBox; + +public class TestIndexInPackageFiles extends JavadocTester { + + public static void main(String... args) throws Exception { + TestIndexInPackageFiles tester = new TestIndexInPackageFiles (); + tester.runTests(); + } + + ToolBox tb = new ToolBox(); + + @Test + public void test() throws IOException { + Path src = Path.of("src"); + tb.writeJavaFiles(src, + "/**\n" + + " * Summary.\n" + + " * {@index test.name.1 additional info}\n" + + " * {@systemProperty test.property.1}\n" + + " */\n" + + "package p.q;", + "package p.q;\n" + + "/** This is a class in p.q. */\n" + + "public class C { }\n"); + + tb.writeFile(src.resolve("p/q/doc-files/extra.html"), + "<html><head><title>Extra</title></head><body>\n" + + "<h1>Extra</h1>\n" + + "{@index test.name.2 additional info}\n" + + "{@systemProperty test.property.2}\n" + + "</body></html>\n"); + + tb.writeFile("overview.html", + "<html><head><title>Overview</title></head><body>\n" + + "<h1>Overview</h1>\n" + + "{@index test.name.3 additional info}\n" + + "</body></html>\n"); + + + javadoc("-d", "out", + "-sourcepath", src.toString(), + "-overview", "overview.html", + "p.q"); + + checkExit(Exit.OK); + + // Note there is an implicit call to checkLinks, but that only + // checks the links are valid if they are actually present. + // Here, we specifically check for both ends of each link. + // However, we assume the search index files are generated appropriately, + // to match the A-Z index files checked here. + + checkOutput("p/q/package-summary.html", true, + "<a id=\"test.name.1\" class=\"searchTagResult\">test.name.1</a>", + "<a id=\"test.property.1\" class=\"searchTagResult\">test.property.1</a>"); + + checkOutput("p/q/doc-files/extra.html", true, + "<a id=\"test.name.2\" class=\"searchTagResult\">test.name.2</a>", + "<a id=\"test.property.2\" class=\"searchTagResult\">test.property.2</a>"); + + checkOutput("index.html", true, + "<a id=\"test.name.3\" class=\"searchTagResult\">test.name.3</a>"); + + checkOutput("index-all.html", true, + "<span class=\"searchTagLink\"><a href=\"p/q/package-summary.html#test.name.1\">test.name.1</a></span>", + "<span class=\"searchTagLink\"><a href=\"p/q/doc-files/extra.html#test.name.2\">test.name.2</a></span>", + "<span class=\"searchTagLink\"><a href=\"index.html#test.name.3\">test.name.3</a></span> - Search tag in Overview</dt>", + "<span class=\"searchTagLink\"><a href=\"p/q/package-summary.html#test.property.1\">test.property.1</a></span>", + "<span class=\"searchTagLink\"><a href=\"p/q/doc-files/extra.html#test.property.2\">test.property.2</a></span>"); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testLinkOption/TestRedirectLinks.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8190312 + * @summary test redirected URLs for -link + * @library /tools/lib ../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.javadoc/jdk.javadoc.internal.api + * jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox toolbox.JavacTask JavadocTester + * @run main TestRedirectLinks + */ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyStore; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManagerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; + +import toolbox.JavacTask; +import toolbox.ToolBox; + + +public class TestRedirectLinks extends JavadocTester { + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String... args) throws Exception { + TestRedirectLinks tester = new TestRedirectLinks(); + tester.runTests(); + } + + private ToolBox tb = new ToolBox(); + + /* + * This test requires access to a URL that is redirected + * from http: to https:. + * For now, we use the main JDK API on docs.oracle.com. + * The test is skipped if access to the server is not available. + * (A better solution is to use a local testing web server.) + */ + @Test + public void testRedirects() throws Exception { + // first, test to see if access to external URLs is available + URL testURL = new URL("http://docs.oracle.com/en/java/javase/11/docs/api/element-list"); + boolean haveRedirectURL = false; + try { + URLConnection conn = testURL.openConnection(); + conn.connect(); + out.println("Opened connection to " + testURL); + if (conn instanceof HttpURLConnection) { + HttpURLConnection httpConn = (HttpURLConnection) conn; + int status = httpConn.getResponseCode(); + if (status / 100 == 3) { + haveRedirectURL = true; + } + out.println("Status: " + status); + int n = 0; + while (httpConn.getHeaderField(n) != null) { + out.println("Header: " + httpConn.getHeaderFieldKey(n) + ": " + httpConn.getHeaderField(n)); + n++; + } + } + } catch (Exception e) { + out.println("Exception occurred: " + e); + } + + if (!haveRedirectURL) { + out.println("Setup failed; this test skipped"); + return; + } + + String apiURL = "http://docs.oracle.com/en/java/javase/11/docs/api"; + String outRedirect = "outRedirect"; + javadoc("-d", outRedirect, + "-html4", + "-sourcepath", testSrc, + "-link", apiURL, + "pkg"); + checkExit(Exit.OK); + checkOutput("pkg/B.html", true, + "<a href=\"" + apiURL + "/java.base/java/lang/String.html?is-external=true\" " + + "title=\"class or interface in java.lang\" class=\"externalLink\">Link-Plain to String Class</a>"); + checkOutput("pkg/C.html", true, + "<a href=\"" + apiURL + "/java.base/java/lang/Object.html?is-external=true\" " + + "title=\"class or interface in java.lang\" class=\"externalLink\">Object</a>"); + } + + private Path libApi = Path.of("libApi"); + private HttpServer oldServer = null; + private HttpsServer newServer = null; + + /** + * This test verifies redirection using temporary localhost web servers, + * such that one server redirects to the other. + */ + @Test + public void testWithServers() throws Exception { + // Set up a simple library + Path libSrc = Path.of("libSrc"); + tb.writeJavaFiles(libSrc.resolve("mA"), + "module mA { exports p1; exports p2; }", + "package p1; public class C1 { }", + "package p2; public class C2 { }"); + tb.writeJavaFiles(libSrc.resolve("mB"), + "module mB { exports p3; exports p4; }", + "package p3; public class C3 { }", + "package p4; public class C4 { }"); + + Path libModules = Path.of("libModules"); + Files.createDirectories(libModules); + + new JavacTask(tb) + .outdir(libModules) + .options("--module-source-path", libSrc.toString(), + "--module", "mA,mB") + .run() + .writeAll(); + + javadoc("-d", libApi.toString(), + "--module-source-path", libSrc.toString(), + "--module", "mA,mB" ); + + // start web servers + InetAddress localHost = InetAddress.getLocalHost(); + try { + oldServer = HttpServer.create(new InetSocketAddress(localHost, 0), 0); + String oldURL = "http:/" + oldServer.getAddress(); + oldServer.createContext("/", this::handleOldRequest); + out.println("Starting old server (" + oldServer.getClass().getSimpleName() + ") on " + oldURL); + oldServer.start(); + + SSLContext sslContext = new SimpleSSLContext().get(); + newServer = HttpsServer.create(new InetSocketAddress(localHost, 0), 0); + String newURL = "https:/" + newServer.getAddress(); + newServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); + newServer.createContext("/", this::handleNewRequest); + out.println("Starting new server (" + newServer.getClass().getSimpleName() + ") on " + newURL); + newServer.start(); + + // Set up API to use that library + Path src = Path.of("src"); + tb.writeJavaFiles(src.resolve("mC"), + "module mC { requires mA; requires mB; exports p5; exports p6; }", + "package p5; public class C5 extends p1.C1 { }", + "package p6; public class C6 { public p4.C4 c4; }"); + + // Set defaults for HttpsURLConfiguration for the duration of this + // invocation of javadoc to use our testing sslContext + HostnameVerifier prevHostNameVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); + SSLSocketFactory prevSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory(); + try { + HttpsURLConnection.setDefaultHostnameVerifier((hostName, session) -> true); + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + + javadoc("-d", "api", + "--module-source-path", src.toString(), + "--module-path", libModules.toString(), + "-link", "http:/" + oldServer.getAddress(), + "--module", "mC" ); + + } finally { + HttpsURLConnection.setDefaultHostnameVerifier(prevHostNameVerifier); + HttpsURLConnection.setDefaultSSLSocketFactory(prevSSLSocketFactory); + } + + // Verify the following: + // 1: A warning about the redirection is generated. + // 2: The contents of the redirected link were read successfully, + // identifying the remote API + // 3: The original URL is still used in the generated docs, to avoid assuming + // that all the other files at that link have been redirected as well. + checkOutput(Output.OUT, true, + "javadoc: warning - URL " + oldURL + "/element-list was redirected to " + newURL + "/element-list"); + checkOutput("mC/p5/C5.html", true, + "extends <a href=\"" + oldURL + "/mA/p1/C1.html?is-external=true\" " + + "title=\"class or interface in p1\" class=\"externalLink\">C1</a>"); + checkOutput("mC/p6/C6.html", true, + "<a href=\"" + oldURL + "/mB/p4/C4.html?is-external=true\" " + + "title=\"class or interface in p4\" class=\"externalLink\">C4</a>"); + } finally { + if (oldServer != null) { + out.println("Stopping old server on " + oldServer.getAddress()); + oldServer.stop(0); + } + if (newServer != null) { + out.println("Stopping new server on " + newServer.getAddress()); + newServer.stop(0); + } + } + } + + private void handleOldRequest(HttpExchange x) throws IOException { + out.println("old request: " + + x.getProtocol() + " " + + x.getRequestMethod() + " " + + x.getRequestURI()); + String newProtocol = (newServer instanceof HttpsServer) ? "https" : "http"; + String redirectTo = newProtocol + ":/" + newServer.getAddress() + x.getRequestURI(); + out.println(" redirect to: " + redirectTo); + x.getResponseHeaders().add("Location", redirectTo); + x.sendResponseHeaders(HttpURLConnection.HTTP_MOVED_PERM, 0); + x.getResponseBody().close(); + } + + private void handleNewRequest(HttpExchange x) throws IOException { + out.println("new request: " + + x.getProtocol() + " " + + x.getRequestMethod() + " " + + x.getRequestURI()); + Path file = libApi.resolve(x.getRequestURI().getPath().substring(1).replace('/', File.separatorChar)); + System.err.println(file); + if (Files.exists(file)) { + byte[] bytes = Files.readAllBytes(file); + // in the context of this test, the only request should be element-list, + // which we can say is text/plain. + x.getResponseHeaders().add("Content-type", "text/plain"); + x.sendResponseHeaders(HttpURLConnection.HTTP_OK, bytes.length); + try (OutputStream responseStream = x.getResponseBody()) { + responseStream.write(bytes); + } + } else { + x.sendResponseHeaders(HttpURLConnection.HTTP_NOT_FOUND, 0); + x.getResponseBody().close(); + } + } + + /** + * Creates a simple usable SSLContext for an HttpsServer using + * a default keystore in the test tree. + * <p> + * This class is based on + * test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java + */ + static class SimpleSSLContext { + + private final SSLContext ssl; + + /** + * Loads default keystore. + */ + SimpleSSLContext() throws Exception { + Path p = Path.of(System.getProperty("test.src", ".")).toAbsolutePath(); + while (!Files.exists(p.resolve("TEST.ROOT"))) { + p = p.getParent(); + if (p == null) { + throw new IOException("can't find TEST.ROOT"); + } + } + + System.err.println("Test suite root: " + p); + Path testKeys = p.resolve("../lib/jdk/test/lib/net/testkeys").normalize(); + if (!Files.exists(testKeys)) { + throw new IOException("can't find testkeys"); + } + System.err.println("Test keys: " + testKeys); + + try (InputStream fis = Files.newInputStream(testKeys)) { + ssl = init(fis); + } + } + + private SSLContext init(InputStream i) throws Exception { + char[] passphrase = "passphrase".toCharArray(); + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(i, passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX"); + tmf.init(ks); + + SSLContext ssl = SSLContext.getInstance("TLS"); + ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return ssl; + } + + SSLContext get() { + return ssl; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/switchexpr/SwitchExpressionIsNotAConstant.java Tue Nov 27 10:59:24 2018 +0530 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8214113 + * @summary Verify the switch expression's type does not have a constant attached, + * and so the switch expression is not elided. + * @compile --enable-preview --source 12 SwitchExpressionIsNotAConstant.java + * @run main/othervm --enable-preview SwitchExpressionIsNotAConstant + */ +public class SwitchExpressionIsNotAConstant { + + public static void main(String[] args) { + int i = 0; + { + i = 0; + int dummy = 1 + switch (i) { + default -> { + i++; + break 1; + } + }; + if (i != 1) { + throw new IllegalStateException("Side effects missing."); + } + } + { + i = 0; + int dummy = 1 + switch (i) { + case -1 -> 1; + default -> { + i++; + break 1; + } + }; + if (i != 1) { + throw new IllegalStateException("Side effects missing."); + } + } + { + i = 0; + int dummy = 1 + switch (i) { + default : + i++; + break 1; + }; + if (i != 1) { + throw new IllegalStateException("Side effects missing."); + } + } + { + i = 0; + int dummy = 1 + switch (i) { + case -1: break 1; + default: + i++; + break 1; + }; + if (i != 1) { + throw new IllegalStateException("Side effects missing."); + } + } + } + +}
--- a/test/lib/jdk/test/lib/process/ProcessTools.java Tue Nov 27 10:45:54 2018 +0530 +++ b/test/lib/jdk/test/lib/process/ProcessTools.java Tue Nov 27 10:59:24 2018 +0530 @@ -464,7 +464,10 @@ */ public static OutputAnalyzer executeCommand(ProcessBuilder pb) throws Throwable { - String cmdLine = pb.command().stream().collect(Collectors.joining(" ")); + String cmdLine = pb.command().stream() + .map(x -> (x.contains(" ") || x.contains("$")) + ? ("'" + x + "'") : x) + .collect(Collectors.joining(" ")); System.out.println("Command line: [" + cmdLine + "]"); OutputAnalyzer analyzer = ProcessTools.executeProcess(pb); System.out.println(analyzer.getOutput());