This commit is contained in:
Prasanta Sadhukhan 2018-11-27 10:59:24 +05:30
commit 06c91fcf7f
28 changed files with 1195 additions and 193 deletions

View File

@ -2870,7 +2870,8 @@ void ADLParser::ins_encode_parse_block(InstructForm& inst) {
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 @@ void ADLParser::constant_parse(InstructForm& inst) {
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);
}

View File

@ -759,19 +759,27 @@ const char *Expr::compute_expr(const Expr *c1, const Expr *c2) {
}
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 {

View File

@ -919,7 +919,8 @@ void InstructForm::build_components() {
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 @@ void InstructForm::build_components() {
// 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 @@ void OperandForm::build_components() {
// 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);

View File

@ -221,23 +221,22 @@ bool DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
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;

View File

@ -327,7 +327,7 @@ void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
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)

View File

@ -441,11 +441,6 @@ void HeapShared::initialize_from_archived_subgraph(Klass* k) {
// 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 @@ void HeapShared::initialize_from_archived_subgraph(Klass* k) {
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));
}
}
}
}

View File

@ -107,36 +107,6 @@ template <MEMFLAGS F> void BasicHashtable<F>::free_buckets() {
}
}
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; }

View File

@ -204,25 +204,6 @@ protected:
// 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);

View File

@ -37,6 +37,7 @@ import java.util.Locale;
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;
@ -2972,6 +2973,25 @@ public final class String
return indent(indent > n ? Integer.MIN_VALUE : indent, true);
}
/**
* 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.
*

View File

@ -1813,8 +1813,8 @@ public class KeyStore {
}
}
throw new KeyStoreException("Unrecognized keystore format: " +
keystore);
throw new KeyStoreException("This keystore does not support probing "
+ "and must be loaded with a specified type");
}
/**

View File

@ -530,22 +530,22 @@ enum SSLCipher {
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;

View File

@ -1328,28 +1328,39 @@ public final class Main {
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") :

View File

@ -1778,9 +1778,6 @@ public class Attr extends JCTree.Visitor {
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)))

View File

@ -169,7 +169,7 @@ public class DocFilesHandlerImpl implements DocFilesHandler {
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);

View File

@ -139,19 +139,6 @@ public class HtmlDoclet extends AbstractDoclet {
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 @@ public class HtmlDoclet extends AbstractDoclet {
}
}
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);

View File

@ -41,11 +41,11 @@ import com.sun.source.doctree.SystemPropertyTree;
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 @@ public class TagletWriterImpl extends TagletWriter {
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;
}

View File

@ -230,6 +230,7 @@ doclet.linkMismatch_PackagedLinkedtoModule=The code being documented uses packag
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=\

View File

@ -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.Element;
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 @@ public class Extern {
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 class Extern {
*/
public boolean isModule(String elementName) {
Item elem = moduleItems.get(elementName);
return (elem == null) ? false : true;
return elem != null;
}
/**
@ -245,14 +253,6 @@ public class Extern {
}
}
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 @@ public class Extern {
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 @@ public class Extern {
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 @@ public class Extern {
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 @@ public class Extern {
}
}
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 @@ public class Extern {
}
}
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;
}
}

View File

@ -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
*/

View File

@ -186,13 +186,19 @@ public class MallocStressTest {
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;
}
}

View File

@ -41,8 +41,13 @@ import sun.hotspot.WhiteBox;
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 @@ public class ReplaceCriticalClasses {
}
}
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 @@ public class ReplaceCriticalClasses {
"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 @@ public class ReplaceCriticalClasses {
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 @@ public class ReplaceCriticalClasses {
} 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 @@ public class ReplaceCriticalClasses {
"-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 @@ public class ReplaceCriticalClasses {
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);
}
}
});
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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>");
}
}

View File

@ -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;
}
}
}

View File

@ -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.");
}
}
}
}

View File

@ -464,7 +464,10 @@ public final class ProcessTools {
*/
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());