--- a/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -374,3 +374,4 @@
e8373543a3f0f60589b7d72b1f9b172721124caf jdk-9+129
e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130
4d2a15091124488080d65848b704e25599b2aaeb jdk-9+131
+2e83d21d78cd9c1d52e6cd2599e9c8aa36ea1f52 jdk-9+132
--- a/.hgtags-top-repo Wed Jul 20 15:07:48 2016 +0200
+++ b/.hgtags-top-repo Mon Aug 29 08:53:32 2016 -0700
@@ -374,3 +374,4 @@
f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
+a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
--- a/common/autoconf/spec.gmk.in Wed Jul 20 15:07:48 2016 +0200
+++ b/common/autoconf/spec.gmk.in Mon Aug 29 08:53:32 2016 -0700
@@ -251,8 +251,6 @@
# Legacy support
USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
-MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@
-
# JDK_OUTPUTDIR specifies where a working jvm is built.
# You can run $(JDK_OUTPUTDIR)/bin/java
# Though the layout of the contents of $(JDK_OUTPUTDIR) is not
--- a/corba/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/corba/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -374,3 +374,4 @@
c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129
77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130
f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
+1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132
--- a/corba/src/java.corba/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/corba/src/java.corba/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,9 @@
* questions.
*/
+/**
+ * Defines the Java binding of the OMG CORBA APIs, and the RMI-IIOP API.
+ */
module java.corba {
requires public java.desktop;
requires public java.rmi;
--- a/hotspot/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -534,3 +534,4 @@
e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
+713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
--- a/hotspot/make/Dist.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/make/Dist.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -46,15 +46,6 @@
endif
################################################################################
-# Functions to setup copying of files for variants
-
-# Support macro for SetupDistLibFile
-define macosx_universalize
- $(MKDIR) -p $(@D)
- $(LIPO) -create -output $@ $<
-endef
-
-################################################################################
# Setup make rules to copy a native library and associated data.
#
# Parameter 1 is the name of the rule. This name is used as variable prefix,
@@ -74,16 +65,9 @@
$1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME)
$1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR)
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- # We must use the 'universalize' macro to run lipo on shared libraries, at
- # least until JDK-8069540 is fixed.
- $1_MACRO := macosx_universalize
- endif
-
# Copy the the native library.
$$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \
DEST := $$($1_TARGET_DIR), \
- MACRO := $$($1_MACRO), \
FILES := $$(wildcard \
$$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \
))
--- a/hotspot/make/test/JtregNative.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/make/test/JtregNative.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -50,7 +50,6 @@
$(HOTSPOT_TOPDIR)/test/runtime/BoolReturn \
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
$(HOTSPOT_TOPDIR)/test/compiler/calls \
- $(HOTSPOT_TOPDIR)/test/compiler/native \
$(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \
$(HOTSPOT_TOPDIR)/test/testlibrary/jvmti \
$(HOTSPOT_TOPDIR)/test/compiler/jvmci/jdk.vm.ci.code.test \
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -110,17 +110,7 @@
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
-
- if (!fp_safe) return false;
-
- // Validate the JavaCallWrapper an entry frame must have
-
- address jcw = (address)entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
-
- return jcw_safe;
-
+ return fp_safe && is_entry_frame_valid(thread);
}
intptr_t* sender_sp = NULL;
@@ -210,15 +200,8 @@
}
// construct the potential sender
-
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
-
- // Validate the JavaCallWrapper an entry frame must have
- address jcw = (address)sender.entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
-
- return jcw_safe;
+ return sender.is_entry_frame_valid(thread);
}
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -225,19 +225,7 @@
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
-
- if (!fp_safe) {
- return false;
- }
-
- // Validate the JavaCallWrapper an entry frame must have
-
- address jcw = (address)entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP);
-
- return jcw_safe;
-
+ return fp_safe && is_entry_frame_valid(thread);
}
intptr_t* younger_sp = sp();
@@ -290,14 +278,8 @@
return false;
}
- if( sender.is_entry_frame()) {
- // Validate the JavaCallWrapper an entry frame must have
-
- address jcw = (address)sender.entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp);
-
- return jcw_safe;
+ if (sender.is_entry_frame()) {
+ return sender.is_entry_frame_valid(thread);
}
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
@@ -357,12 +339,6 @@
_cb = CodeCache::find_blob(_pc);
}
_deopt_state = unknown;
-#ifdef ASSERT
- if ( _cb != NULL && _cb->is_compiled()) {
- // Without a valid unextended_sp() we can't convert the pc to "original"
- assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken");
- }
-#endif // ASSERT
}
frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) {
@@ -534,6 +510,7 @@
void frame::patch_pc(Thread* thread, address pc) {
+ vmassert(_deopt_state != unknown, "frame is unpatchable");
if(thread == Thread::current()) {
StubRoutines::Sparc::flush_callers_register_windows_func()();
}
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -108,17 +108,7 @@
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
-
- if (!fp_safe) return false;
-
- // Validate the JavaCallWrapper an entry frame must have
-
- address jcw = (address)entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
-
- return jcw_safe;
-
+ return fp_safe && is_entry_frame_valid(thread);
}
intptr_t* sender_sp = NULL;
@@ -209,15 +199,8 @@
}
// construct the potential sender
-
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
-
- // Validate the JavaCallWrapper an entry frame must have
- address jcw = (address)sender.entry_frame_call_wrapper();
-
- bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
-
- return jcw_safe;
+ return sender.is_entry_frame_valid(thread);
}
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -1071,6 +1071,9 @@
NOT_LP64(get_thread(rthread);)
+ cmpl(Address(rthread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_enabled);
+ jcc(Assembler::equal, no_reserved_zone_enabling);
+
cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset()));
jcc(Assembler::lessEqual, no_reserved_zone_enabling);
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Mon Aug 29 08:53:32 2016 -0700
@@ -255,7 +255,8 @@
}
buildAttachArgs(newArgs, pid, exe, core, false);
- JStack.main(newArgs.toArray(new String[newArgs.size()]));
+ JStack jstack = new JStack(false, false);
+ jstack.runWithArgs(newArgs.toArray(new String[newArgs.size()]));
}
private static void runJMAP(String[] oldArgs) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Mon Aug 29 08:53:32 2016 -0700
@@ -46,7 +46,6 @@
private static final int SENDER_SP_OFFSET = 0;
// Interpreter frames
- private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4;
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1;
@@ -55,7 +54,8 @@
private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1;
private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1;
- private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
+ private static final int INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
+ private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway
private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java Mon Aug 29 08:53:32 2016 -0700
@@ -714,11 +714,7 @@
/** 2 words, also used to save float regs across calls to C */
public static final int INTERPRETER_FRAME_D_SCRATCH_FP_OFFSET = -2;
public static final int INTERPRETER_FRAME_L_SCRATCH_FP_OFFSET = -4;
- /** For native calls only */
- public static final int INTERPRETER_FRAME_PADDING_OFFSET = -5;
- /** For native calls only */
- public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -6;
- /** Should be same as above, and should be zero mod 8 */
+ public static final int INTERPRETER_FRAME_MIRROR_OFFSET = -5;
public static final int INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET = -6;
public static final int INTERPRETER_FRAME_VM_LOCAL_WORDS = -INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java Mon Aug 29 08:53:32 2016 -0700
@@ -48,10 +48,10 @@
private static final int SENDER_SP_OFFSET = 2;
// Interpreter frames
- private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
+ private static int INTERPRETER_FRAME_MIRROR_OFFSET;
private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only
private static int INTERPRETER_FRAME_CACHE_OFFSET;
private static int INTERPRETER_FRAME_LOCALS_OFFSET;
@@ -74,7 +74,8 @@
}
private static synchronized void initialize(TypeDataBase db) {
- INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
+ INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
+ INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,6 +26,7 @@
import java.lang.reflect.Modifier;
import java.util.*;
+import java.util.stream.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
@@ -204,15 +205,29 @@
}
}
- protected Object getHashtable(Instance oop, boolean isProperties) {
+ private void setPropertiesEntry(java.util.Properties p, Oop oop) {
+ InstanceKlass ik = (InstanceKlass)oop.getKlass();
+ OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;");
+ OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;");
+
+ try {
+ p.setProperty((String)readObject(keyField.getValue(oop)),
+ (String)readObject(valueField.getValue(oop)));
+ } catch (ClassNotFoundException ce) {
+ if (DEBUG) {
+ debugPrintStackTrace(ce);
+ }
+ }
+ }
+
+ protected Object getHashtable(Instance oop) {
InstanceKlass k = (InstanceKlass)oop.getKlass();
OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;");
if (tableField == null) {
debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;");
return null;
}
- java.util.Hashtable table = (isProperties) ? new java.util.Properties()
- : new java.util.Hashtable();
+ java.util.Hashtable table = new java.util.Hashtable();
ObjArray kvs = (ObjArray)tableField.getValue(oop);
long size = kvs.getLength();
debugPrintln("Hashtable$Entry Size = " + size);
@@ -225,6 +240,39 @@
return table;
}
+ private Properties getProperties(Instance oop) {
+ InstanceKlass k = (InstanceKlass)oop.getKlass();
+ OopField mapField = (OopField)k.findField("map", "Ljava/util/concurrent/ConcurrentHashMap;");
+ if (mapField == null) {
+ debugPrintln("Could not find field of Ljava/util/concurrent/ConcurrentHashMap");
+ return null;
+ }
+
+ Instance mapObj = (Instance)mapField.getValue(oop);
+ if (mapObj == null) {
+ debugPrintln("Could not get map field from java.util.Properties");
+ return null;
+ }
+
+ InstanceKlass mk = (InstanceKlass)mapObj.getKlass();
+ OopField tableField = (OopField)mk.findField("table", "[Ljava/util/concurrent/ConcurrentHashMap$Node;");
+ if (tableField == null) {
+ debugPrintln("Could not find field of [Ljava/util/concurrent/ConcurrentHashMap$Node");
+ return null;
+ }
+
+ java.util.Properties props = new java.util.Properties();
+ ObjArray kvs = (ObjArray)tableField.getValue(mapObj);
+ long size = kvs.getLength();
+ debugPrintln("ConcurrentHashMap$Node Size = " + size);
+ LongStream.range(0, size)
+ .mapToObj(kvs::getObjAt)
+ .filter(o -> o != null)
+ .forEach(o -> setPropertiesEntry(props, o));
+
+ return props;
+ }
+
public Object readInstance(Instance oop) throws ClassNotFoundException {
Object result = getFromObjTable(oop);
if (result == null) {
@@ -240,11 +288,11 @@
}
if (kls.getName().equals(javaUtilHashtable())) {
- return getHashtable(oop, false);
+ return getHashtable(oop);
}
if (kls.getName().equals(javaUtilProperties())) {
- return getHashtable(oop, true);
+ return getProperties(oop);
}
Class clz = readClass(kls);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Mon Aug 29 08:53:32 2016 -0700
@@ -265,9 +265,10 @@
native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError;
/**
- * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index {@code cpi} in
- * {@code constantPool}. For some opcodes, checks are performed that require the {@code method}
- * that contains {@code opcode} to be specified. The values returned in {@code info} are:
+ * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry for at index
+ * {@code cpi} in {@code constantPool}. For some opcodes, checks are performed that require the
+ * {@code method} that contains {@code opcode} to be specified. The values returned in
+ * {@code info} are:
*
* <pre>
* [(int) flags, // only valid if field is resolved
@@ -556,20 +557,18 @@
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
/**
- * Read a HotSpot ConstantPool* value from the memory location described by {@code base} plus
- * {@code displacement} and return the {@link HotSpotConstantPool} wrapping it. This method does
- * no checking that the memory location actually contains a valid pointer and may crash the VM
- * if an invalid location is provided. If the {@code base} is null then {@code displacement} is
- * used by itself. If {@code base} is a {@link HotSpotResolvedJavaMethodImpl},
- * {@link HotSpotConstantPool} or {@link HotSpotResolvedObjectTypeImpl} then the metaspace
- * pointer is fetched from that object and added to {@code displacement}. Any other non-null
- * object type causes an {@link IllegalArgumentException} to be thrown.
+ * Gets the {@code ConstantPool*} associated with {@code object} and returns a
+ * {@link HotSpotConstantPool} wrapping it.
*
- * @param base an object to read from or null
- * @param displacement
- * @return null or the resolved method for this location
+ * @param object a {@link HotSpotResolvedJavaMethodImpl} or
+ * {@link HotSpotResolvedObjectTypeImpl} object
+ * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with
+ * {@code object}
+ * @throws NullPointerException if {@code object == null}
+ * @throws IllegalArgumentException if {@code object} is neither a
+ * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
*/
- native HotSpotConstantPool getConstantPool(Object base, long displacement);
+ native HotSpotConstantPool getConstantPool(Object object);
/**
* Read a HotSpot Klass* value from the memory location described by {@code base} plus
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -121,7 +121,7 @@
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
- this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
+ this.constantPool = compilerToVM().getConstantPool(this);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -445,7 +445,7 @@
* operating on the latest one and that HotSpotResolvedJavaMethodImpls will be able to
* use the shared copy instead of creating their own instance.
*/
- constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
+ constantPool = compilerToVM().getConstantPool(this);
}
return constantPool;
}
--- a/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -2686,7 +2686,8 @@
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
-// Note that the SR_lock plays no role in this suspend/resume protocol.
+// Note that the SR_lock plays no role in this suspend/resume protocol,
+// but is checked for NULL in SR_handler as a thread termination indicator.
//
static void resume_clear_context(OSThread *osthread) {
@@ -2718,9 +2719,22 @@
// after sigsuspend.
int old_errno = errno;
- Thread* thread = Thread::current();
+ Thread* thread = Thread::current_or_null_safe();
+ assert(thread != NULL, "Missing current thread in SR_handler");
+
+ // On some systems we have seen signal delivery get "stuck" until the signal
+ // mask is changed as part of thread termination. Check that the current thread
+ // has not already terminated (via SR_lock()) - else the following assertion
+ // will fail because the thread is no longer a JavaThread as the ~JavaThread
+ // destructor has completed.
+
+ if (thread->SR_lock() == NULL) {
+ return;
+ }
+
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
OSThread* osthread = thread->osthread();
- assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -2716,7 +2716,8 @@
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
-// Note that the SR_lock plays no role in this suspend/resume protocol.
+// Note that the SR_lock plays no role in this suspend/resume protocol,
+// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@@ -2746,9 +2747,22 @@
// after sigsuspend.
int old_errno = errno;
- Thread* thread = Thread::current();
+ Thread* thread = Thread::current_or_null_safe();
+ assert(thread != NULL, "Missing current thread in SR_handler");
+
+ // On some systems we have seen signal delivery get "stuck" until the signal
+ // mask is changed as part of thread termination. Check that the current thread
+ // has not already terminated (via SR_lock()) - else the following assertion
+ // will fail because the thread is no longer a JavaThread as the ~JavaThread
+ // destructor has completed.
+
+ if (thread->SR_lock() == NULL) {
+ return;
+ }
+
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
OSThread* osthread = thread->osthread();
- assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -3971,7 +3971,8 @@
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
-// Note that the SR_lock plays no role in this suspend/resume protocol.
+// Note that the SR_lock plays no role in this suspend/resume protocol,
+// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@@ -4004,8 +4005,20 @@
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
+
+ // On some systems we have seen signal delivery get "stuck" until the signal
+ // mask is changed as part of thread termination. Check that the current thread
+ // has not already terminated (via SR_lock()) - else the following assertion
+ // will fail because the thread is no longer a JavaThread as the ~JavaThread
+ // destructor has completed.
+
+ if (thread->SR_lock() == NULL) {
+ return;
+ }
+
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
OSThread* osthread = thread->osthread();
- assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
--- a/hotspot/src/os/posix/vm/os_posix.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -93,10 +93,6 @@
}
int os::get_native_stack(address* stack, int frames, int toSkip) {
-#ifdef _NMT_NOINLINE_
- toSkip++;
-#endif
-
int frame_idx = 0;
int num_of_frames; // number of frames captured
frame fr = os::current_frame();
--- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -318,9 +318,6 @@
// only supported on Windows XP or later.
//
int os::get_native_stack(address* stack, int frames, int toSkip) {
-#ifdef _NMT_NOINLINE_
- toSkip++;
-#endif
int captured = RtlCaptureStackBackTrace(toSkip + 1, frames, (PVOID*)stack, NULL);
for (int index = captured; index < frames; index ++) {
stack[index] = NULL;
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -417,7 +417,15 @@
#else
register intptr_t **ebp __asm__ (SPELL_REG_FP);
#endif
- return (intptr_t*) *ebp; // we want what it points to.
+ // ebp is for this frame (_get_previous_fp). We want the ebp for the
+ // caller of os::current_frame*(), so go up two frames. However, for
+ // optimized builds, _get_previous_fp() will be inlined, so only go
+ // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+ return **(intptr_t***)ebp;
+#else
+ return *ebp;
+#endif
}
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -238,6 +238,28 @@
}
}
+ // Make the signal handler transaction-aware by checking the existence of a
+ // second (transactional) context with MSR TS bits active. If the signal is
+ // caught during a transaction, then just return to the HTM abort handler.
+ // Please refer to Linux kernel document powerpc/transactional_memory.txt,
+ // section "Signals".
+ if (uc && uc->uc_link) {
+ ucontext_t* second_uc = uc->uc_link;
+
+ // MSR TS bits are 29 and 30 (Power ISA, v2.07B, Book III-S, pp. 857-858,
+ // 3.2.1 "Machine State Register"), however note that ISA notation for bit
+ // numbering is MSB 0, so for normal bit numbering (LSB 0) they come to be
+ // bits 33 and 34. It's not related to endianness, just a notation matter.
+ if (second_uc->uc_mcontext.regs->msr & 0x600000000) {
+ if (TraceTraps) {
+ tty->print_cr("caught signal in transaction, "
+ "ignoring to jump to abort handler");
+ }
+ // Return control to the HTM abort handler.
+ return true;
+ }
+ }
+
JavaThread* thread = NULL;
VMThread* vmthread = NULL;
if (os::Linux::signal_handlers_are_installed) {
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -235,7 +235,15 @@
#else
register intptr_t **ebp __asm__ (SPELL_REG_FP);
#endif
- return (intptr_t*) *ebp; // we want what it points to.
+ // ebp is for this frame (_get_previous_fp). We want the ebp for the
+ // caller of os::current_frame*(), so go up two frames. However, for
+ // optimized builds, _get_previous_fp() will be inlined, so only go
+ // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+ return **(intptr_t***)ebp;
+#else
+ return *ebp;
+#endif
}
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -292,15 +292,19 @@
frame os::current_frame() {
intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
+ // fp is for os::current_frame. We want the fp for our caller.
frame myframe((intptr_t*)os::current_stack_pointer(),
(intptr_t*)fp,
CAST_FROM_FN_PTR(address, os::current_frame));
- if (os::is_first_C_frame(&myframe)) {
+ frame caller_frame = os::get_sender_for_C_frame(&myframe);
+
+ if (os::is_first_C_frame(&caller_frame)) {
// stack is not walkable
frame ret; // This will be a null useless frame
return ret;
} else {
- return os::get_sender_for_C_frame(&myframe);
+ // return frame for our caller's caller
+ return os::get_sender_for_C_frame(&caller_frame);
}
}
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -496,7 +496,15 @@
__asm {
mov frameptr, ebp
};
+ // ebp (frameptr) is for this frame (_get_previous_fp). We want the ebp for the
+ // caller of os::current_frame*(), so go up two frames. However, for
+ // optimized builds, _get_previous_fp() will be inlined, so only go
+ // up 1 frame in that case.
+#ifdef _NMT_NOINLINE_
+ return **(intptr_t***)frameptr;
+#else
return *frameptr;
+#endif
}
#endif // !AMD64
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -126,13 +126,17 @@
// ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while
// it is being defined, therefore _keep_alive is not volatile or atomic.
void ClassLoaderData::inc_keep_alive() {
- assert(_keep_alive >= 0, "Invalid keep alive count");
- _keep_alive++;
+ if (is_anonymous()) {
+ assert(_keep_alive >= 0, "Invalid keep alive increment count");
+ _keep_alive++;
+ }
}
void ClassLoaderData::dec_keep_alive() {
- assert(_keep_alive > 0, "Invalid keep alive count");
- _keep_alive--;
+ if (is_anonymous()) {
+ assert(_keep_alive > 0, "Invalid keep alive decrement count");
+ _keep_alive--;
+ }
}
void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
@@ -1173,7 +1177,7 @@
if (class_loader() == NULL) {
out->print("NULL class_loader");
} else {
- out->print("class loader " INTPTR_FORMAT, p2i(this));
+ out->print("class loader " INTPTR_FORMAT " ", p2i(this));
class_loader()->print_value_on(out);
}
}
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -176,9 +176,9 @@
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away
bool _is_anonymous; // if this CLD is for an anonymous class
- int _keep_alive; // if this CLD is kept alive without a keep_alive_object().
- // Currently used solely for anonymous classes.
- // _keep_alive does not need to be volatile or
+ s2 _keep_alive; // if this CLD is kept alive without a keep_alive_object().
+ // Used for anonymous classes and the boot class
+ // loader. _keep_alive does not need to be volatile or
// atomic since there is one unique CLD per anonymous class.
volatile int _claimed; // true if claimed, for example during GC traces.
// To avoid applying oop closure more than once.
@@ -289,6 +289,8 @@
return _unloading;
}
+ // Used to refcount an anonymous class's CLD in order to
+ // indicate their aliveness without a keep_alive_object().
void inc_keep_alive();
void dec_keep_alive();
--- a/hotspot/src/share/vm/code/dependencies.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/code/dependencies.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -1082,12 +1082,11 @@
if (!(m->is_public() || m->is_protected()))
// The override story is complex when packages get involved.
return true; // Must punt the assertion to true.
- Klass* k = ctxk;
- Method* lm = k->lookup_method(m->name(), m->signature());
- if (lm == NULL && k->is_instance_klass()) {
+ Method* lm = ctxk->lookup_method(m->name(), m->signature());
+ if (lm == NULL && ctxk->is_instance_klass()) {
// It might be an interface method
- lm = InstanceKlass::cast(k)->lookup_method_in_ordered_interfaces(m->name(),
- m->signature());
+ lm = InstanceKlass::cast(ctxk)->lookup_method_in_ordered_interfaces(m->name(),
+ m->signature());
}
if (lm == m)
// Method m is inherited into ctxk.
@@ -1101,11 +1100,19 @@
// Static methods don't override non-static so punt
return true;
}
- if ( !Dependencies::is_concrete_method(lm, k)
- && !Dependencies::is_concrete_method(m, ctxk)
- && lm->method_holder()->is_subtype_of(m->method_holder()))
- // Method m is overridden by lm, but both are non-concrete.
- return true;
+ if (!Dependencies::is_concrete_method(lm, ctxk) &&
+ !Dependencies::is_concrete_method(m, ctxk)) {
+ // They are both non-concrete
+ if (lm->method_holder()->is_subtype_of(m->method_holder())) {
+ // Method m is overridden by lm, but both are non-concrete.
+ return true;
+ }
+ if (lm->method_holder()->is_interface() && m->method_holder()->is_interface() &&
+ ctxk->is_subtype_of(m->method_holder()) && ctxk->is_subtype_of(lm->method_holder())) {
+ // Interface method defined in multiple super interfaces
+ return true;
+ }
+ }
}
ResourceMark rm;
tty->print_cr("Dependency method not found in the associated context:");
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -316,8 +316,12 @@
return get_new_size_prediction(_pending_cards_seq);
}
+double G1Analytics::oldest_known_gc_end_time_sec() const {
+ return _recent_prev_end_times_for_all_gcs_sec->oldest();
+}
+
double G1Analytics::last_known_gc_end_time_sec() const {
- return _recent_prev_end_times_for_all_gcs_sec->oldest();
+ return _recent_prev_end_times_for_all_gcs_sec->last();
}
void G1Analytics::update_recent_gc_times(double end_time_sec,
--- a/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -155,6 +155,7 @@
void update_recent_gc_times(double end_time_sec, double elapsed_ms);
void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
+ double oldest_known_gc_end_time_sec() const;
double last_known_gc_end_time_sec() const;
};
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
#include "classfile/symbolTable.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
+#include "gc/g1/g1Analytics.hpp"
#include "gc/g1/bufferingOopClosure.hpp"
#include "gc/g1/concurrentG1Refine.hpp"
#include "gc/g1/concurrentG1RefineThread.hpp"
@@ -2473,8 +2474,19 @@
}
jlong G1CollectedHeap::millis_since_last_gc() {
- // assert(false, "NYI");
- return 0;
+ jlong now = os::elapsed_counter() / NANOSECS_PER_MILLISEC;
+ const G1Analytics* analytics = _g1_policy->analytics();
+ double last = analytics->last_known_gc_end_time_sec();
+ jlong ret_val = now - (last * 1000);
+ if (ret_val < 0) {
+ // See the notes in GenCollectedHeap::millis_since_last_gc()
+ // for more information about the implementation.
+ log_warning(gc)("Detected clock going backwards. "
+ "Milliseconds since last GC would be " JLONG_FORMAT
+ ". returning zero instead.", ret_val);
+ return 0;
+ }
+ return ret_val;
}
void G1CollectedHeap::prepare_for_verify() {
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -604,7 +604,7 @@
_analytics->report_alloc_rate_ms(alloc_rate_ms);
double interval_ms =
- (end_time_sec - _analytics->last_known_gc_end_time_sec()) * 1000.0;
+ (end_time_sec - _analytics->oldest_known_gc_end_time_sec()) * 1000.0;
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
_analytics->compute_pause_time_ratio(interval_ms, pause_time_ms);
}
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -1256,21 +1256,21 @@
};
jlong GenCollectedHeap::millis_since_last_gc() {
- // We need a monotonically non-decreasing time in ms but
- // os::javaTimeMillis() does not guarantee monotonicity.
+ // javaTimeNanos() is guaranteed to be monotonically non-decreasing
+ // provided the underlying platform provides such a time source
+ // (and it is bug free). So we still have to guard against getting
+ // back a time later than 'now'.
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
GenTimeOfLastGCClosure tolgc_cl(now);
// iterate over generations getting the oldest
// time that a generation was collected
generation_iterate(&tolgc_cl, false);
- // javaTimeNanos() is guaranteed to be monotonically non-decreasing
- // provided the underlying platform provides such a time source
- // (and it is bug free). So we still have to guard against getting
- // back a time later than 'now'.
jlong retVal = now - tolgc_cl.time();
if (retVal < 0) {
- NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
+ log_warning(gc)("Detected clock going backwards. "
+ "Milliseconds since last GC would be " JLONG_FORMAT
+ ". returning zero instead.", retVal);
return 0;
}
return retVal;
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -461,31 +461,26 @@
return JNIHandles::make_local(THREAD, result);
}
-C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset))
+C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject object_handle))
constantPoolHandle cp;
- oop base_object = JNIHandles::resolve(base);
- jlong base_address = 0;
- if (base_object != NULL) {
- if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
- base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
- } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
- base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
- } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
- base_address = (jlong) CompilerToVM::asKlass(base_object);
- } else {
- THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
- err_msg("Unexpected type: %s", base_object->klass()->external_name()));
- }
+ oop object = JNIHandles::resolve(object_handle);
+ if (object == NULL) {
+ THROW_0(vmSymbols::java_lang_NullPointerException());
}
- cp = *((ConstantPool**) (intptr_t) (base_address + offset));
- if (!cp.is_null()) {
- JavaValue method_result(T_OBJECT);
- JavaCallArguments args;
- args.push_long((jlong) (address) cp());
- JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
- return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
+ if (object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+ cp = CompilerToVM::asMethod(object)->constMethod()->constants();
+ } else if (object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
+ cp = InstanceKlass::cast(CompilerToVM::asKlass(object))->constants();
+ } else {
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+ err_msg("Unexpected type: %s", object->klass()->external_name()));
}
- return NULL;
+ assert(!cp.is_null(), "npe");
+ JavaValue method_result(T_OBJECT);
+ JavaCallArguments args;
+ args.push_long((jlong) (address) cp());
+ JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
+ return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
}
C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
@@ -1522,7 +1517,7 @@
{CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},
{CC "getResolvedJavaMethodAtSlot", CC "(" CLASS "I)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethodAtSlot)},
{CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
- {CC "getConstantPool", CC "(Ljava/lang/Object;J)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
+ {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
{CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
{CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
{CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},
--- a/hotspot/src/share/vm/logging/logTagSet.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/oops/methodCounters.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/vm/opto/arraycopynode.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/opto/arraycopynode.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -630,6 +630,12 @@
}
bool ArrayCopyNode::may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase, ArrayCopyNode*& ac) {
+ if (n->Opcode() == Op_StoreCM ||
+ n->Opcode() == Op_StoreB) {
+ // Ignore card mark stores
+ n = n->in(MemNode::Memory);
+ }
+
if (n->is_Proj()) {
n = n->in(0);
if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) {
@@ -657,9 +663,6 @@
}
}
}
- } else if (n->Opcode() == Op_StoreCM) {
- // Ignore card mark stores
- return may_modify_helper(t_oop, n->in(MemNode::Memory), phase, ac);
}
}
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -1703,29 +1703,51 @@
}
if (uncasted) {
- // Add a cast node between the phi to be removed and its unique input.
+ // Add cast nodes between the phi to be removed and its unique input.
// Wait until after parsing for the type information to propagate from the casts.
assert(can_reshape, "Invalid during parsing");
const Type* phi_type = bottom_type();
assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type");
- int opcode;
- // Determine the type of cast to be added.
+ // Add casts to carry the control dependency of the Phi that is
+ // going away
+ Node* cast = NULL;
if (phi_type->isa_int()) {
- opcode = Op_CastII;
+ cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true);
} else {
const Type* uin_type = phase->type(uin);
- if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) ||
- (!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) {
- opcode = Op_CastPP;
+ if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
+ cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
} else {
- opcode = Op_CheckCastPP;
+ // Use a CastPP for a cast to not null and a CheckCastPP for
+ // a cast to a new klass (and both if both null-ness and
+ // klass change).
+
+ // If the type of phi is not null but the type of uin may be
+ // null, uin's type must be casted to not null
+ if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
+ uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
+ cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true);
+ }
+
+ // If the type of phi and uin, both casted to not null,
+ // differ the klass of uin must be (check)cast'ed to match
+ // that of phi
+ if (phi_type->join_speculative(TypePtr::NOTNULL) != uin_type->join_speculative(TypePtr::NOTNULL)) {
+ Node* n = uin;
+ if (cast != NULL) {
+ cast = phase->transform(cast);
+ n = cast;
+ }
+ cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true);
+ }
+ if (cast == NULL) {
+ cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
+ }
}
}
- // Add a cast to carry the control dependency of the Phi that is
- // going away
- Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true);
+ assert(cast != NULL, "cast should be set");
cast = phase->transform(cast);
- // set all inputs to the new cast so the Phi is removed by Identity
+ // set all inputs to the new cast(s) so the Phi is removed by Identity
PhaseIterGVN* igvn = phase->is_IterGVN();
for (uint i = 1; i < req(); i++) {
set_req_X(i, cast, igvn);
--- a/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -861,6 +861,13 @@
}
const Klass* host_klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(host_class));
+
+ // Make sure it's the real host class, not another anonymous class.
+ while (host_klass != NULL && host_klass->is_instance_klass() &&
+ InstanceKlass::cast(host_klass)->is_anonymous()) {
+ host_klass = InstanceKlass::cast(host_klass)->host_klass();
+ }
+
// Primitive types have NULL Klass* fields in their java.lang.Class instances.
if (host_klass == NULL) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
--- a/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -679,7 +679,7 @@
WB_END
WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel))
- if (compLevel < CompLevel_none || compLevel > CompLevel_highest_tier) {
+ if (compLevel < CompLevel_none || compLevel > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) {
return false; // Intrinsic is not available on a non-existent compilation level.
}
jmethodID method_id, compilation_context_id;
@@ -689,6 +689,7 @@
DirectiveSet* directive;
AbstractCompiler* comp = CompileBroker::compiler((int)compLevel);
+ assert(comp != NULL, "compiler not available");
if (compilation_context != NULL) {
compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
@@ -698,7 +699,7 @@
// Calling with NULL matches default directive
directive = DirectivesStack::getDefaultDirective(comp);
}
- bool result = CompileBroker::compiler(compLevel)->is_intrinsic_available(mh, directive);
+ bool result = comp->is_intrinsic_available(mh, directive);
DirectivesStack::release(directive);
return result;
WB_END
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -55,7 +55,8 @@
// Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
int log_cpu = log2_intptr(os::active_processor_count());
int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
- count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2;
+ count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
+ FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#else
// On 32-bit systems, the number of compiler threads is limited to 3.
@@ -67,12 +68,18 @@
/// available to the VM and thus cause the VM to crash.
if (FLAG_IS_DEFAULT(CICompilerCount)) {
count = 3;
+ FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#endif
- set_c1_count(MAX2(count / 3, 1));
- set_c2_count(MAX2(count - c1_count(), 1));
- FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
+ if (TieredStopAtLevel < CompLevel_full_optimization) {
+ // No C2 compiler thread required
+ set_c1_count(count);
+ } else {
+ set_c1_count(MAX2(count / 3, 1));
+ set_c2_count(MAX2(count - c1_count(), 1));
+ }
+ assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
// Some inlining tuning
#ifdef X86
--- a/hotspot/src/share/vm/runtime/frame.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/frame.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -225,6 +225,19 @@
return NULL;
}
+bool frame::is_entry_frame_valid(JavaThread* thread) const {
+ // Validate the JavaCallWrapper an entry frame must have
+ address jcw = (address)entry_frame_call_wrapper();
+ bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)fp()); // less than stack base
+ if (!jcw_safe) {
+ return false;
+ }
+
+ // Validate sp saved in the java frame anchor
+ JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
+ return (jfa->last_Java_sp() > sp());
+}
+
bool frame::should_be_deoptimized() const {
if (_deopt_state == is_deoptimized ||
!is_compiled_frame() ) return false;
--- a/hotspot/src/share/vm/runtime/frame.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/frame.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -166,6 +166,8 @@
frame sender_for_interpreter_frame(RegisterMap* map) const;
frame sender_for_native_frame(RegisterMap* map) const;
+ bool is_entry_frame_valid(JavaThread* thread) const;
+
// All frames:
// A low-level interface for vframes:
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Aug 29 08:53:32 2016 -0700
@@ -2411,7 +2411,7 @@
product(intx, CICompilerCount, CI_COMPILER_COUNT, \
"Number of compiler threads to run") \
range(0, max_jint) \
- constraint(CICompilerCountConstraintFunc, AtParse) \
+ constraint(CICompilerCountConstraintFunc, AfterErgo) \
\
product(intx, CompilationPolicyChoice, 0, \
"which compilation policy (0-3)") \
--- a/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -660,11 +660,13 @@
}
const Klass* host_class = current_class;
- while (host_class->is_instance_klass() &&
- InstanceKlass::cast(host_class)->is_anonymous()) {
- const Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass();
- if (next_host_class == NULL) break;
- host_class = next_host_class;
+ if (host_class->is_instance_klass() &&
+ InstanceKlass::cast(host_class)->is_anonymous()) {
+ host_class = InstanceKlass::cast(host_class)->host_klass();
+ assert(host_class != NULL, "Anonymous class has null host class");
+ assert(!(host_class->is_instance_klass() &&
+ InstanceKlass::cast(host_class)->is_anonymous()),
+ "host_class should not be anonymous");
}
if (host_class == field_class) {
return true;
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -147,12 +147,18 @@
// performed on 32-bit systems because it can lead to exhaustion
// of the virtual memory address space available to the JVM.
if (CICompilerCountPerCPU) {
- count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2;
+ count = MAX2(log2_intptr(os::active_processor_count()) * 3 / 2, 2);
+ FLAG_SET_ERGO(intx, CICompilerCount, count);
}
#endif
- set_c1_count(MAX2(count / 3, 1));
- set_c2_count(MAX2(count - c1_count(), 1));
- FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count());
+ if (TieredStopAtLevel < CompLevel_full_optimization) {
+ // No C2 compiler thread required
+ set_c1_count(count);
+ } else {
+ set_c1_count(MAX2(count / 3, 1));
+ set_c2_count(MAX2(count - c1_count(), 1));
+ }
+ assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
}
void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -374,11 +374,14 @@
delete handle_area();
delete metadata_handles();
+ // SR_handler uses this as a termination indicator -
+ // needs to happen before os::free_thread()
+ delete _SR_lock;
+ _SR_lock = NULL;
+
// osthread() can be NULL, if creation of thread failed.
if (osthread() != NULL) os::free_thread(osthread());
- delete _SR_lock;
-
// clear Thread::current if thread is deleting itself.
// Needed to ensure JNI correctly detects non-attached threads.
if (this == Thread::current()) {
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -2643,7 +2643,7 @@
/* DEFAULT_CACHE_LINE_SIZE (globalDefinitions.hpp) */ \
/***************************************************/ \
\
- declare_constant(DEFAULT_CACHE_LINE_SIZE) \
+ declare_preprocessor_constant("DEFAULT_CACHE_LINE_SIZE", DEFAULT_CACHE_LINE_SIZE) \
\
declare_constant(Deoptimization::Unpack_deopt) \
declare_constant(Deoptimization::Unpack_exception) \
--- a/hotspot/src/share/vm/utilities/nativeCallStack.cpp Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/src/share/vm/utilities/nativeCallStack.cpp Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,19 @@
_hash_value(0) {
if (fillStack) {
+ // We need to skip the NativeCallStack::NativeCallStack frame if a tail call is NOT used
+ // to call os::get_native_stack. A tail call is used if _NMT_NOINLINE_ is not defined
+ // (which means this is not a slowdebug build), and we are on 64-bit (except Windows).
+ // This is not necessarily a rule, but what has been obvserved to date.
+#define TAIL_CALL (!defined(_NMT_NOINLINE_) && !defined(WINDOWS) && defined(_LP64))
+#if !TAIL_CALL
+ toSkip++;
+#if (defined(_NMT_NOINLINE_) && defined(BSD) && defined(_LP64))
+ // Mac OS X slowdebug builds have this odd behavior where NativeCallStack::NativeCallStack
+ // appears as two frames, so we need to skip an extra frame.
+ toSkip++;
+#endif
+#endif
os::get_native_stack(_stack, NMT_TrackingStackDepth, toSkip);
} else {
for (int index = 0; index < NMT_TrackingStackDepth; index ++) {
--- a/hotspot/test/Makefile Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/Makefile Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -226,6 +226,9 @@
( \
jtregExitCode=$$? && \
_summary="$(SUMMARY_TXT)"; \
+ if [ $${jtregExitCode} = 1 ] ; then \
+ jtregExitCode=0; \
+ fi; \
$(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
$(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
if [ -r "$${_summary}" ] ; then \
--- a/hotspot/test/TEST.groups Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/TEST.groups Mon Aug 29 08:53:32 2016 -0700
@@ -167,7 +167,7 @@
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
runtime/NMT/JcmdSummaryDiff.java \
- runtime/RedefineTests/RedefineAnnotations.java
+ runtime/RedefineTests/RedefineAnnotations.java \
serviceability/sa/jmap-hashcode/Test8028623.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/codecache/jmx \
@@ -282,7 +282,7 @@
-compiler/c2/Test6905845.java \
-compiler/c2/cr6340864 \
-compiler/c2/cr6589834 \
- -compiler/c2/cr8004867
+ -compiler/c2/cr8004867 \
-compiler/c2/stemmer \
-compiler/c2/Test6792161.java \
-compiler/c2/Test6603011.java \
--- a/hotspot/test/compiler/arguments/CheckCICompilerCount.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/arguments/CheckCICompilerCount.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,8 +23,7 @@
/*
* @test CheckCheckCICompilerCount
- * @bug 8130858
- * @bug 8132525
+ * @bug 8130858 8132525 8162881
* @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not
* @library /testlibrary /
* @modules java.base/jdk.internal.misc
@@ -54,6 +53,13 @@
"-version"
},
{
+ "-server",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-XX:-TieredCompilation",
+ "-version"
+ },
+ {
"-client",
"-XX:-TieredCompilation",
"-XX:+PrintFlagsFinal",
@@ -66,30 +72,31 @@
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
+ },
+ {
+ "-client",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-XX:-TieredCompilation",
+ "-version"
}
};
- private static final String[][] NON_TIERED_EXPECTED_OUTPUTS = {
- {
+ private static final String[] NON_TIERED_EXPECTED_OUTPUTS = {
"CICompilerCount (0) must be at least 1",
- "Improperly specified VM option 'CICompilerCount=0'"
- },
- {
+ "intx CICompilerCount = 1 {product} {command line}",
+ "intx CICompilerCount = 1 {product} {command line}",
+ "CICompilerCount (0) must be at least 1",
+ "intx CICompilerCount = 1 {product} {command line}",
"intx CICompilerCount = 1 {product} {command line}"
- },
- {
- "CICompilerCount (0) must be at least 1",
- "Improperly specified VM option 'CICompilerCount=0'"
- },
- {
- "intx CICompilerCount = 1 {product} {command line}"
- }
};
private static final int[] NON_TIERED_EXIT = {
1,
0,
+ 0,
1,
+ 0,
0
};
@@ -104,6 +111,22 @@
{
"-server",
"-XX:+TieredCompilation",
+ "-XX:TieredStopAtLevel=1",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-version"
+ },
+ {
+ "-server",
+ "-XX:+TieredCompilation",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-XX:TieredStopAtLevel=1",
+ "-version"
+ },
+ {
+ "-server",
+ "-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=2",
"-version"
@@ -118,37 +141,51 @@
{
"-client",
"-XX:+TieredCompilation",
+ "-XX:TieredStopAtLevel=1",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-version"
+ },
+ {
+ "-client",
+ "-XX:+TieredCompilation",
+ "-XX:+PrintFlagsFinal",
+ "-XX:CICompilerCount=1",
+ "-XX:TieredStopAtLevel=1",
+ "-version"
+ },
+ {
+ "-client",
+ "-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=2",
"-version"
}
};
- private static final String[][] TIERED_EXPECTED_OUTPUTS = {
- {
+ private static final String[] TIERED_EXPECTED_OUTPUTS = {
"CICompilerCount (1) must be at least 2",
- "Improperly specified VM option 'CICompilerCount=1'"
- },
- {
- "intx CICompilerCount = 2 {product} {command line, ergonomic}"
- },
- {
+ "intx CICompilerCount = 1 {product} {command line}",
+ "intx CICompilerCount = 1 {product} {command line}",
+ "intx CICompilerCount = 2 {product} {command line}",
"CICompilerCount (1) must be at least 2",
- "Improperly specified VM option 'CICompilerCount=1'"
- },
- {
- "intx CICompilerCount = 2 {product} {command line, ergonomic}"
- }
+ "intx CICompilerCount = 1 {product} {command line}",
+ "intx CICompilerCount = 1 {product} {command line}",
+ "intx CICompilerCount = 2 {product} {command line}",
};
private static final int[] TIERED_EXIT = {
1,
0,
+ 0,
+ 0,
1,
+ 0,
+ 0,
0
};
- private static void verifyValidOption(String[] arguments, String[] expected_outputs, int exit, boolean tiered) throws Exception {
+ private static void verifyValidOption(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception {
ProcessBuilder pb;
OutputAnalyzer out;
@@ -157,9 +194,7 @@
try {
out.shouldHaveExitValue(exit);
- for (String expected_output : expected_outputs) {
- out.shouldContain(expected_output);
- }
+ out.shouldContain(expected_output);
} catch (RuntimeException e) {
// Check if tiered compilation is available in this JVM
// Version. Throw exception only if it is available.
--- a/hotspot/test/compiler/arraycopy/TestEliminatedArrayCopyDeopt.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/arraycopy/TestEliminatedArrayCopyDeopt.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,7 +25,6 @@
* @test
* @bug 8130847 8156760
* @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt
- * @ignore 8136818
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
* compiler.arraycopy.TestEliminatedArrayCopyDeopt
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
--- a/hotspot/test/compiler/c2/Test6792161.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/c2/Test6792161.java Mon Aug 29 08:53:32 2016 -0700
@@ -27,7 +27,7 @@
* @bug 6792161
* @summary assert("No dead instructions after post-alloc")
*
- * @run main/othervm/timeout=600 -Xcomp -XX:MaxInlineSize=120 compiler.c2.Test6792161
+ * @run main/othervm/timeout=600 -Xcomp -XX:-TieredCompilation -XX:MaxInlineSize=120 compiler.c2.Test6792161
*/
package compiler.c2;
--- a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -36,6 +36,11 @@
* -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages
* -XX:+SegmentedCodeCache
* compiler.codecache.jmx.InitialAndMaxUsageTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
+ * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:CompileCommand=compileonly,null::* -XX:-UseLargePages
+ * -XX:-SegmentedCodeCache
+ * compiler.codecache.jmx.InitialAndMaxUsageTest
*/
package compiler.codecache.jmx;
@@ -70,10 +75,16 @@
}
}
- private void fillWithSize(long size, List<Long> blobs) {
+ private void fillWithSize(long size, List<Long> blobs, MemoryPoolMXBean bean) {
long blob;
- while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id))
- != 0L) {
+ /* Don't fill too much to have space for adapters. So, stop after crossing 95% and
+ don't allocate in case we'll cross 97% on next allocation. We can hit situation
+ like 94% -> (1 allocation) -> 100% otherwise. So, check if
+ <Usage + allocatedSize> is less than 97%, then allocate in case it is, then, stop
+ further allocations with given size in case <Usage> more than 95% */
+ while (((double) bean.getUsage().getUsed() + size <= (CACHE_USAGE_COEF + 0.02d) * maxSize)
+ && (blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) != 0L
+ && ((double) bean.getUsage().getUsed() <= CACHE_USAGE_COEF * maxSize)) {
blobs.add(blob);
}
}
@@ -90,13 +101,13 @@
Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage");
}
ArrayList<Long> blobs = new ArrayList<>();
- long minAllocationUnit = Math.max(0, CodeCacheUtils.MIN_ALLOCATION - headerSize);
+ long minAllocationUnit = Math.max(1, CodeCacheUtils.MIN_ALLOCATION - headerSize);
/* now filling code cache with large-sized allocation first, since
lots of small allocations takes too much time, so, just a small
optimization */
try {
for (int coef = 1000000; coef > 0; coef /= 10) {
- fillWithSize(coef * minAllocationUnit, blobs);
+ fillWithSize(coef * minAllocationUnit, blobs, bean);
}
Asserts.assertGT((double) bean.getUsage().getUsed(),
CACHE_USAGE_COEF * maxSize, String.format("Unable to fill "
--- a/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -31,11 +31,11 @@
* @build compiler.codecache.jmx.ThresholdNotificationsTest
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::*
* -XX:+SegmentedCodeCache
* compiler.codecache.jmx.ThresholdNotificationsTest
- * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing
* -XX:+WhiteBoxAPI -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::*
* -XX:-SegmentedCodeCache
* compiler.codecache.jmx.ThresholdNotificationsTest
@@ -63,7 +63,9 @@
public static void main(String[] args) {
for (BlobType bt : BlobType.getAvailable()) {
- new ThresholdNotificationsTest(bt).runTest();
+ if (CodeCacheUtils.isCodeHeapPredictable(bt)) {
+ new ThresholdNotificationsTest(bt).runTest();
+ }
}
}
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -63,7 +63,9 @@
public static void main(String[] args) {
int iterationsCount = Integer.getInteger("jdk.test.lib.iterations", 1);
for (BlobType btype : BlobType.getAvailable()) {
- new UsageThresholdExceededTest(btype, iterationsCount).runTest();
+ if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
+ new UsageThresholdExceededTest(btype, iterationsCount).runTest();
+ }
}
}
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,9 +29,9 @@
* @modules java.base/jdk.internal.misc
* java.management
*
+ * @build compiler.codecache.jmx.UsageThresholdIncreasedTest
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @build compiler.codecache.jmx.UsageThresholdIncreasedTest
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:-UseCodeCacheFlushing -XX:-MethodFlushing
* -XX:CompileCommand=compileonly,null::*
--- a/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,6 +24,7 @@
/*
* @test RandomAllocationTest
+ * @key stress
* @summary stressing code cache by allocating randomly sized "dummy" code blobs
* @library /testlibrary /test/lib /
* @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,6 +24,7 @@
/*
* @test UnexpectedDeoptimizationTest
+ * @key stress
* @summary stressing code cache by forcing unexpected deoptimizations
* @library /testlibrary /test/lib /
* @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/codegen/aes/TestAESMain.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/codegen/aes/TestAESMain.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,6 +25,7 @@
/**
* @test
* @bug 7184394
+ * @key stress
* @summary add intrinsics to use AES instructions
* @library /testlibrary /
* @modules java.base/jdk.internal.misc
--- a/hotspot/test/compiler/floatingpoint/ModNaN.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/floatingpoint/ModNaN.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,7 +26,6 @@
* @bug 8015396
* @summary double a%b returns NaN for some (a,b) (|a| < inf, |b|>0) (on Core i7 980X)
*
- * @ignore 8145543
* @run main compiler.floatingpoint.ModNaN
*/
--- a/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -114,7 +114,7 @@
public void test() throws Exception {
Executable intrinsicMethod = testCase.getExecutable();
- if (Platform.isServer()) {
+ if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
if (TIERED_COMPILATION) {
checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
}
--- a/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -59,9 +59,9 @@
private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/* Determine if tiered compilation is enabled. */
- private static boolean isTieredCompilationEnabled() {
- return Boolean.valueOf(Objects.toString(wb.getVMFlag("TieredCompilation")));
- }
+ private static final boolean TIERED_COMPILATION = wb.getBooleanVMFlag("TieredCompilation");
+
+ private static final int TIERED_STOP_AT_LEVEL = wb.getIntxVMFlag("TieredStopAtLevel").intValue();
/* This test uses several methods from jdk.internal.misc.Unsafe. The method
* getMethod() returns a different Executable for each different
@@ -202,8 +202,8 @@
}
public static void main(String args[]) {
- if (Platform.isServer()) {
- if (isTieredCompilationEnabled()) {
+ if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
+ if (TIERED_COMPILATION) {
test(COMP_LEVEL_SIMPLE);
}
test(COMP_LEVEL_FULL_OPTIMIZATION);
--- a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Mon Aug 29 08:53:32 2016 -0700
@@ -273,8 +273,8 @@
return CTVM.getResolvedJavaMethod(base, displacement);
}
- public static HotSpotConstantPool getConstantPool(Object base, long displacement) {
- return CTVM.getConstantPool(base, displacement);
+ public static HotSpotConstantPool getConstantPool(Object object) {
+ return CTVM.getConstantPool(object);
}
public static HotSpotResolvedObjectType getResolvedJavaType(Object base,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/DuplicateSimpleSingleImplementerInterface.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.jvmci.common.testcases;
+
+public interface DuplicateSimpleSingleImplementerInterface {
+ void interfaceMethod();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/MultipleSuperImplementers.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.jvmci.common.testcases;
+
+public abstract class MultipleSuperImplementers implements DuplicateSimpleSingleImplementerInterface, SimpleSingleImplementerInterface {
+ public void finalize() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/testcases/SimpleSingleImplementerInterface.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.jvmci.common.testcases;
+
+public interface SimpleSingleImplementerInterface {
+ void interfaceMethod();
+}
--- a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -32,6 +32,8 @@
* java.base/jdk.internal.org.objectweb.asm.tree
* jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.code
+ * jdk.vm.ci/jdk.vm.ci.meta
+ * jdk.vm.ci/jdk.vm.ci.runtime
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
* @build compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
@@ -41,7 +43,10 @@
package compiler.jvmci.compilerToVM;
import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.DuplicateSimpleSingleImplementerInterface;
+import compiler.jvmci.common.testcases.SimpleSingleImplementerInterface;
import compiler.jvmci.common.testcases.MultipleImplementer1;
+import compiler.jvmci.common.testcases.MultipleSuperImplementers;
import compiler.jvmci.common.testcases.SingleImplementer;
import compiler.jvmci.common.testcases.SingleImplementerInterface;
import compiler.jvmci.common.testcases.SingleSubclass;
@@ -96,6 +101,11 @@
// static method
result.add(new TestCase(false, SingleSubclass.class,
SingleSubclass.class, "staticMethod"));
+ // interface method
+ result.add(new TestCase(false, MultipleSuperImplementers.class,
+ DuplicateSimpleSingleImplementerInterface.class, "interfaceMethod", false));
+ result.add(new TestCase(false, MultipleSuperImplementers.class,
+ SimpleSingleImplementerInterface.class, "interfaceMethod", false));
return result;
}
@@ -103,7 +113,7 @@
System.out.println(tcase);
Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
HotSpotResolvedJavaMethod testMethod = CTVMUtilities
- .getResolvedMethod(tcase.receiver, method);
+ .getResolvedMethod(tcase.methodFromReceiver ? tcase.receiver : tcase.holder, method);
HotSpotResolvedObjectType resolvedType = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.receiver), getClass(),
/* resolve = */ true);
@@ -118,20 +128,25 @@
public final Class<?> holder;
public final String methodName;
public final boolean isPositive;
+ public final boolean methodFromReceiver;
public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder,
- String methodName) {
+ String methodName, boolean methodFromReceiver) {
this.receiver = clazz;
this.methodName = methodName;
this.isPositive = isPositive;
this.holder = holder;
+ this.methodFromReceiver = methodFromReceiver;
+ }
+
+ public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder, String methodName) {
+ this(isPositive, clazz, holder, methodName, true);
}
@Override
public String toString() {
- return String.format("CASE: receiver=%s, holder=%s, method=%s,"
- + " isPositive=%s", receiver.getName(),
- holder.getName(), methodName, isPositive);
+ return String.format("CASE: receiver=%s, holder=%s, method=%s, isPositive=%s, methodFromReceiver=%s",
+ receiver.getName(), holder.getName(), methodName, isPositive, methodFromReceiver);
}
}
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,187 +29,76 @@
* @library /testlibrary /test/lib /
* @library ../common/patches
* @modules java.base/jdk.internal.misc
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ java.base/jdk.internal.org.objectweb.asm.tree
+ jdk.vm.ci/jdk.vm.ci.hotspot
* jdk.vm.ci/jdk.vm.ci.meta
+ * jdk.vm.ci/jdk.vm.ci.code
*
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject
* @build compiler.jvmci.compilerToVM.GetConstantPoolTest
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:.
- * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+UnlockDiagnosticVMOptions
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
* compiler.jvmci.compilerToVM.GetConstantPoolTest
*/
package compiler.jvmci.compilerToVM;
-import jdk.internal.misc.Unsafe;
import jdk.test.lib.Utils;
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.jvmci.common.testcases.TestCase;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.ConstantPool;
-import sun.hotspot.WhiteBox;
import java.lang.reflect.Field;
+import java.lang.reflect.Executable;
/**
* Tests for jdk.vm.ci.hotspot.CompilerToVM::getConstantPool method
*/
public class GetConstantPoolTest {
- private static enum TestCase {
- NULL_BASE {
- @Override
- ConstantPool getConstantPool() {
- return CompilerToVMHelper.getConstantPool(null,
- getPtrToCpAddress());
- }
- },
- JAVA_METHOD_BASE {
- @Override
- ConstantPool getConstantPool() {
- HotSpotResolvedJavaMethod methodInstance
- = CompilerToVMHelper.getResolvedJavaMethodAtSlot(
- TEST_CLASS, 0);
- Field field;
- try {
- // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod
- field = methodInstance.getClass()
- .getDeclaredField("metaspaceMethod");
- field.setAccessible(true);
- field.set(methodInstance, getPtrToCpAddress());
- } catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e, e);
- }
- return CompilerToVMHelper.getConstantPool(methodInstance, 0L);
- }
- },
- CONSTANT_POOL_BASE {
- @Override
- ConstantPool getConstantPool() {
- ConstantPool cpInst;
- try {
- cpInst = CompilerToVMHelper.getConstantPool(null,
- getPtrToCpAddress());
- Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
- .getDeclaredField("metaspaceConstantPool");
- field.setAccessible(true);
- field.set(cpInst, getPtrToCpAddress());
- } catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
- }
- return CompilerToVMHelper.getConstantPool(cpInst, 0L);
- }
- },
- CONSTANT_POOL_BASE_IN_TWO {
- @Override
- ConstantPool getConstantPool() {
- long ptr = getPtrToCpAddress();
- ConstantPool cpInst;
- try {
- cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
- Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
- .getDeclaredField("metaspaceConstantPool");
- field.setAccessible(true);
- field.set(cpInst, ptr / 2L);
- } catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
- }
- return CompilerToVMHelper.getConstantPool(cpInst,
- ptr - ptr / 2L);
- }
- },
- CONSTANT_POOL_BASE_ZERO {
- @Override
- ConstantPool getConstantPool() {
- long ptr = getPtrToCpAddress();
- ConstantPool cpInst;
- try {
- cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
- Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
- .getDeclaredField("metaspaceConstantPool");
- field.setAccessible(true);
- field.set(cpInst, 0L);
- } catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
- }
- return CompilerToVMHelper.getConstantPool(cpInst, ptr);
- }
- },
- ;
- abstract ConstantPool getConstantPool();
+ public static void testMethod(Executable executable) {
+ test(CTVMUtilities.getResolvedMethod(executable));
}
- private static final WhiteBox WB = WhiteBox.getWhiteBox();
- private static final Unsafe UNSAFE = Utils.getUnsafe();
-
- private static final Class TEST_CLASS = GetConstantPoolTest.class;
- private static final long CP_ADDRESS
- = WB.getConstantPool(GetConstantPoolTest.class);
+ public static void testClass(Class cls) {
+ HotSpotResolvedObjectType type = CompilerToVMHelper
+ .lookupType(Utils.toJVMTypeSignature(cls),
+ GetConstantPoolTest.class, /* resolve = */ true);
+ test(type);
+ }
- public void test(TestCase testCase) {
- System.out.println(testCase.name());
- ConstantPool cp = testCase.getConstantPool();
- String cpStringRep = cp.toString();
- String cpClassSimpleName
- = CompilerToVMHelper.HotSpotConstantPoolClass().getSimpleName();
- if (!cpStringRep.contains(cpClassSimpleName)
- || !cpStringRep.contains(TEST_CLASS.getName())) {
- String msg = String.format("%s : "
- + " Constant pool is not valid."
- + " String representation should contain \"%s\" and \"%s\"",
- testCase.name(), cpClassSimpleName,
- TEST_CLASS.getName());
- throw new AssertionError(msg);
- }
+ private static void test(Object object) {
+ ConstantPool cp = CompilerToVMHelper.getConstantPool(object);
+ System.out.println(object + " -> " + cp);
}
public static void main(String[] args) {
- GetConstantPoolTest test = new GetConstantPoolTest();
- for (TestCase testCase : TestCase.values()) {
- test.test(testCase);
- }
- testObjectBase();
- testMetaspaceWrapperBase();
+ TestCase.getAllClasses().forEach(GetConstantPoolTest::testClass);
+ TestCase.getAllExecutables().forEach(GetConstantPoolTest::testMethod);
+ testNull();
+ testObject();
}
- private static void testObjectBase() {
+ private static void testNull() {
try {
- Object cp = CompilerToVMHelper.getConstantPool(new Object(), 0L);
- throw new AssertionError("Test OBJECT_BASE."
+ Object cp = CompilerToVMHelper.getConstantPool(null);
+ throw new AssertionError("Test OBJECT."
+ + " Expected IllegalArgumentException has not been caught");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+ private static void testObject() {
+ try {
+ Object cp = CompilerToVMHelper.getConstantPool(new Object());
+ throw new AssertionError("Test OBJECT."
+ " Expected IllegalArgumentException has not been caught");
} catch (IllegalArgumentException iae) {
// expected
}
}
- private static void testMetaspaceWrapperBase() {
- try {
- Object cp = CompilerToVMHelper.getConstantPool(
- new PublicMetaspaceWrapperObject() {
- @Override
- public long getMetaspacePointer() {
- return getPtrToCpAddress();
- }
- }, 0L);
- throw new AssertionError("Test METASPACE_WRAPPER_BASE."
- + " Expected IllegalArgumentException has not been caught");
- } catch (IllegalArgumentException iae) {
- // expected
- }
- }
-
- private static long getPtrToCpAddress() {
- Field field;
- try {
- field = TEST_CLASS.getDeclaredField("CP_ADDRESS");
- } catch (NoSuchFieldException nsfe) {
- throw new Error("TESTBUG : cannot find field \"CP_ADDRESS\" : "
- + nsfe.getMessage(), nsfe);
- }
- Object base = UNSAFE.staticFieldBase(field);
- return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/runtime/cr8015436/Driver8015436.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.runtime.cr8015436;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class Driver8015436 {
+ public static void main(String args[]) {
+ OutputAnalyzer oa;
+ try {
+ oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(
+ /* add test vm options */ true, Test8015436.class.getName()));
+ } catch (Exception ex) {
+ throw new Error("TESTBUG: exception while running child process: " + ex, ex);
+ }
+ oa.shouldHaveExitValue(0);
+ oa.shouldContain(Test8015436.SOME_MTD_INVOKED);
+ oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_DIRECTLY);
+ oa.shouldContain(Test8015436.DEFAULT_MTD_INVOKED_MH);
+ }
+}
--- a/hotspot/test/compiler/runtime/cr8015436/Test8015436.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/compiler/runtime/cr8015436/Test8015436.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,8 +25,12 @@
* @test
* @bug 8015436
* @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added
+ * @library /test/lib/share/classes /
+ * @modules java.base/jdk.internal.misc
+ * @build compiler.runtime.cr8015436.Test8015436
+ * compiler.runtime.cr8015436.Driver8015436
*
- * @run main compiler.runtime.cr8015436.Test8015436
+ * @run driver compiler.runtime.cr8015436.Driver8015436
*/
/*
@@ -45,20 +49,24 @@
import java.lang.invoke.MethodType;
public class Test8015436 implements InterfaceWithDefaultMethod {
+ public static final String SOME_MTD_INVOKED = "someMethod() invoked";
+ public static final String DEFAULT_MTD_INVOKED_DIRECTLY = "defaultMethod() invoked directly";
+ public static final String DEFAULT_MTD_INVOKED_MH = "defaultMethod() invoked via a MethodHandle";
+
@Override
public void someMethod() {
- System.out.println("someMethod() invoked");
+ System.out.println(SOME_MTD_INVOKED);
}
public static void main(String[] args) throws Throwable {
Test8015436 testObj = new Test8015436();
testObj.someMethod();
- testObj.defaultMethod("invoked directly");
+ testObj.defaultMethod(DEFAULT_MTD_INVOKED_DIRECTLY);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(void.class, String.class);
MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt);
- mh.invokeExact(testObj, "invoked via a MethodHandle");
+ mh.invokeExact(testObj, DEFAULT_MTD_INVOKED_MH);
}
}
@@ -66,7 +74,7 @@
public void someMethod();
default public void defaultMethod(String str){
- System.out.println("defaultMethod() " + str);
+ System.out.println(str);
}
}
/*
--- a/hotspot/test/gc/g1/ihop/TestIHOPErgo.java Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/gc/g1/ihop/TestIHOPErgo.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,6 +24,7 @@
/*
* @test TestIHOPErgo
* @bug 8148397
+ * @key stress
* @summary Test checks that behavior of Adaptive and Static IHOP at concurrent cycle initiation
* @requires vm.gc.G1
* @requires !vm.flightRecorder
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @key nmt
+ * @summary Running with NMT detail should produce expected stack traces.
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ */
+
+import jdk.test.lib.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CheckForProperDetailStackTrace {
+ /* The stack trace we look for by default. Note that :: has been replaced by .*
+ to make sure it maches even if the symbol is not unmangled. */
+ public static String stackTraceDefault =
+ ".*ModuleEntryTable.*new_entry.*\n" +
+ ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
+ ".*Modules.*define_module.*\n" +
+ ".*JVM_DefineModule.*\n";
+
+ /* The stack trace we look for on Solaris and Windows slowdebug builds. For some
+ reason ALWAYSINLINE for AllocateHeap is ignored, so it appears in the stack strace. */
+ public static String stackTraceAllocateHeap =
+ ".*AllocateHeap.*\n" +
+ ".*ModuleEntryTable.*new_entry.*\n" +
+ ".*ModuleEntryTable.*locked_create_entry_or_null.*\n" +
+ ".*Modules.*define_module.*\n";
+
+ /* A symbol that should always be present in NMT detail output. */
+ private static String expectedSymbol =
+ "locked_create_entry_or_null";
+
+ private static final String jdkDebug = System.getProperty("jdk.debug");
+ private static boolean isSlowDebugBuild() {
+ return (jdkDebug.toLowerCase().equals("slowdebug"));
+ }
+
+ public static void main(String args[]) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:NativeMemoryTracking=detail",
+ "-XX:+PrintNMTStatistics",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldHaveExitValue(0);
+
+ // We should never see either of these frames because they are supposed to be skipped. */
+ output.shouldNotContain("NativeCallStack::NativeCallStack");
+ output.shouldNotContain("os::get_native_stack");
+
+ // AllocateHeap shouldn't be in the output because it is suppose to always be inlined.
+ // We check for that here, but allow it for Windows and Solaris slowdebug builds because
+ // the compiler ends up not inlining AllocateHeap.
+ Boolean okToHaveAllocateHeap =
+ isSlowDebugBuild() && (Platform.isSolaris() || Platform.isWindows());
+ if (!okToHaveAllocateHeap) {
+ output.shouldNotContain("AllocateHeap");
+ }
+
+ // See if we have any stack trace symbols in the output
+ boolean hasSymbols =
+ output.getStdout().contains(expectedSymbol) || output.getStderr().contains(expectedSymbol);
+ if (!hasSymbols) {
+ // It's ok for ARM not to have symbols, because it does not support NMT detail
+ // when targeting thumb2. It's also ok for Windows not to have symbols, because
+ // they are only available if the symbols file is included with the build.
+ if (Platform.isWindows() || Platform.isARM()) {
+ return; // we are done
+ }
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Expected symbol missing missing from output: " + expectedSymbol);
+ }
+
+ /* Make sure the expected NMT detail stack trace is found. */
+ String expectedStackTrace =
+ (okToHaveAllocateHeap ? stackTraceAllocateHeap : stackTraceDefault);
+ if (!stackTraceMatches(expectedStackTrace, output)) {
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Expected stack trace missing missing from output: " + expectedStackTrace);
+ }
+ }
+
+ public static boolean stackTraceMatches(String stackTrace, OutputAnalyzer output) {
+ Matcher stdoutMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStdout());
+ Matcher stderrMatcher = Pattern.compile(stackTrace, Pattern.MULTILINE).matcher(output.getStderr());
+ return (stdoutMatcher.find() || stderrMatcher.find());
+ }
+}
--- a/hotspot/test/runtime/StackGuardPages/exeinvoke.c Wed Jul 20 15:07:48 2016 +0200
+++ b/hotspot/test/runtime/StackGuardPages/exeinvoke.c Mon Aug 29 08:53:32 2016 -0700
@@ -242,7 +242,7 @@
CLASS_PATH_OPT, javaclasspath);
options[0].optionString = "-Xint";
- options[1].optionString = "-Xss328k";
+ options[1].optionString = "-Xss1M";
options[2].optionString = javaclasspathopt;
vm_args.version = JNI_VERSION_1_2;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Unsafe/NestedUnsafe.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Creates an anonymous class inside of an anonymous class.
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.compiler
+ * java.management
+ * @run main NestedUnsafe
+ */
+
+import java.security.ProtectionDomain;
+import java.io.InputStream;
+import java.lang.*;
+import jdk.test.lib.*;
+import jdk.internal.misc.Unsafe;
+import static jdk.test.lib.Asserts.*;
+
+// package p;
+
+public class NestedUnsafe {
+ // The String concatenation should create the nested anonymous class.
+ static byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass",
+ "public class TestClass { " +
+ " public static void concat(String one, String two) throws Throwable { " +
+ " System.out.println(one + two);" +
+ " } } ");
+
+ public static void main(String args[]) throws Exception {
+ Unsafe unsafe = Utils.getUnsafe();
+
+ Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]);
+ unsafe.ensureClassInitialized(klass);
+ Class[] cArgs = new Class[2];
+ cArgs[0] = String.class;
+ cArgs[1] = String.class;
+ try {
+ klass.getMethod("concat", cArgs).invoke(null, "AA", "BB");
+ } catch (Throwable ex) {
+ throw new RuntimeException("Exception: " + ex.toString());
+ }
+
+ // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
+ byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2",
+ "import jdk.internal.misc.Unsafe; " +
+ "public class TestClass2 { " +
+ " public static void doit() throws Throwable { " +
+ " Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); " +
+ " Class klass2 = unsafe.defineAnonymousClass(TestClass2.class, NestedUnsafe.klassbuf, new Object[0]); " +
+ " unsafe.ensureClassInitialized(klass2); " +
+ " Class[] dArgs = new Class[2]; " +
+ " dArgs[0] = String.class; " +
+ " dArgs[1] = String.class; " +
+ " try { " +
+ " klass2.getMethod(\"concat\", dArgs).invoke(null, \"CC\", \"DD\"); " +
+ " } catch (Throwable ex) { " +
+ " throw new RuntimeException(\"Exception: \" + ex.toString()); " +
+ " } " +
+ "} } ",
+ "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED");
+ Class klass2 = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf2, new Object[0]);
+ try {
+ klass2.getMethod("doit").invoke(null);
+ } catch (Throwable ex) {
+ throw new RuntimeException("Exception: " + ex.toString());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/sa/sadebugd/SADebugDTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Checks that the jshdb debugd utility sucessfully starts
+ * and tries to attach to a running process
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib/share/classes
+ *
+ * @ignore 8163805
+ * @run main/othervm SADebugDTest
+ */
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.Reader;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import static jdk.test.lib.Asserts.assertTrue;
+import static jdk.test.lib.Platform.shouldSAAttach;
+import static jdk.test.lib.process.ProcessTools.startProcess;
+
+public class SADebugDTest {
+
+ private static final String GOLDEN = "Attaching to process ID %d and starting RMI services, please wait...";
+
+ private static final String JAVA_HOME = (System.getProperty("test.jdk") != null)
+ ? System.getProperty("test.jdk") : System.getProperty("java.home");
+
+ private static final String JAVA_BIN_DIR
+ = JAVA_HOME + File.separator + "bin" + File.separator;
+
+ private static final String JHSDB = JAVA_BIN_DIR + "jhsdb";
+
+ public static void main(String[] args) throws Exception {
+
+ if (!shouldSAAttach()) {
+ log("Not possible to attach the SA. Skipping the test");
+ return;
+ }
+
+ long ourPid = ProcessHandle.current().getPid();
+
+ // The string we are expecting in the debugd ouput
+ String golden = String.format(GOLDEN, ourPid);
+
+ // We are going to run 'jhsdb debugd <our pid>'
+ // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr
+ // In case of timeout startProcess kills the debugd process
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(JHSDB, "debugd", String.valueOf(ourPid));
+ Process debugd = startProcess("debugd", pb, null, (line) -> line.trim().contains(golden), 0, TimeUnit.SECONDS);
+
+ // If we are here, this means we have received the golden line and the test has passed
+ // The debugd remains running, we have to kill it
+ debugd.destroy();
+
+ }
+
+ private static void log(String string) {
+ System.out.println(string);
+ }
+
+}
--- a/jaxp/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -374,3 +374,4 @@
74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129
e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131
+907445d85e680ea410fe2c83c0ec64b5508e4f3e jdk-9+132
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/res/XSLTErrorResources.java Mon Aug 29 08:53:32 2016 -0700
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: XSLTErrorResources.java,v 1.2.4.1 2005/09/13 09:55:37 pvedula Exp $
- */
package com.sun.org.apache.xalan.internal.res;
import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Mon Aug 29 08:53:32 2016 -0700
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/15 09:59:41 pvedula Exp $
- */
package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/ErrorMessages.java Mon Aug 29 08:53:32 2016 -0700
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: ErrorMessages.java,v 1.2.4.1 2005/09/14 05:06:42 pvedula Exp $
- */
package com.sun.org.apache.xalan.internal.xsltc.runtime;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AbortException.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xerces.internal.dom;
+
+public class AbortException extends RuntimeException {
+
+ private static final long serialVersionUID = 2608302175475740417L;
+
+ /**
+ * Constructor AbortException
+ */
+ public AbortException() { super(null, null, false, false); }
+}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,6 +26,7 @@
import java.io.StringReader;
import java.util.Vector;
+import com.sun.org.apache.xerces.internal.dom.AbortException;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
@@ -157,11 +158,6 @@
// attribute value normalization
final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0);
- /**
- * If the user stops the process, this exception will be thrown.
- */
- public static final RuntimeException abort = new RuntimeException();
-
//DTD validator
private XMLDTDValidator fDTDValidator;
@@ -242,11 +238,8 @@
XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
fValidationHandler = null;
}
- }
- catch (RuntimeException e) {
- if( e==abort )
- return; // processing aborted by the user
- throw e; // otherwise re-throw.
+ } catch (AbortException e) {
+ return;
}
}
@@ -1371,10 +1364,10 @@
error.fRelatedData = locator.fRelatedNode;
if(!errorHandler.handleError(error))
- throw abort;
+ throw new AbortException();
}
if( severity==DOMError.SEVERITY_FATAL_ERROR )
- throw abort;
+ throw new AbortException();
}
protected final void updateQName (Node node, QName qname){
@@ -2043,5 +2036,4 @@
return null;
}
-
} // DOMNormalizer class
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -2,8 +2,6 @@
# DOM implementation.
#
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: DOMMessages.properties,v 1.2 2005-08-16 22:51:51 jeffsuttor Exp $
BadMessageKey = The error message corresponding to the message key can not be found.
FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/DatatypeMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -1,8 +1,6 @@
# This file stores localized messages for the Xerces JAXP Datatype API implementation.
#
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: DatatypeMessages.properties 3021 2011-03-01 00:12:28Z joehw $
BadMessageKey = The error message corresponding to the message key can not be found.
FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/JAXPValidationMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -1,8 +1,6 @@
# This file stores localized messages for the Xerces JAXP Validation API implementation.
#
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: JAXPValidationMessages.properties 3021 2011-03-01 00:12:28Z joehw $
# Messages for message reporting
BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/SAXMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -2,8 +2,6 @@
# SAX implementation.
#
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: SAXMessages.properties 3021 2011-03-01 00:12:28Z joehw $
BadMessageKey = The error message corresponding to the message key can not be found.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -1,7 +1,5 @@
# This file contains error and warning messages related to XML Schema
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: XMLSchemaMessages.properties 3021 2011-03-01 00:12:28Z joehw $
BadMessageKey = The error message corresponding to the message key can not be found.
FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLSerializerMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -4,8 +4,6 @@
#
# As usual with properties files, the messages are arranged in
# key/value tuples.
-#
-# @version $Id: XMLSerializerMessages.properties 3021 2011-03-01 00:12:28Z joehw $
BadMessageKey = The error message corresponding to the message key can not be found.
FormatFailed = An internal error occurred while formatting the following message:\n
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XPointerMessages.properties Mon Aug 29 08:53:32 2016 -0700
@@ -1,8 +1,6 @@
# This file stores localized messages for the Xerces XPointer implementation.
#
# The messages are arranged in key and value tuples in a ListResourceBundle.
-#
-# @version $Id: XPointerMessages.properties 3021 2011-03-01 00:12:28Z joehw $
# Messages for message reporting
BadMessageKey = The error message corresponding to the message key can not be found.
@@ -24,4 +22,4 @@
InvalidElementSchemeXPointer = InvalidElementSchemeXPointer: The Element Scheme XPointer expression ''{0}'' is invalid.
XPointerElementSchemeProcessingError = XPointerElementSchemeProcessingError: An error occurred while processing the XPointer element() Scheme expression.
InvalidNCNameInElementSchemeData = InvalidNCNameInElementSchemeData: The element() Scheme contains a ShortHand Pointer ''{0}'' with an invalid NCName.
-InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''.
\ No newline at end of file
+InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/res/XMLErrorResources.java Mon Aug 29 08:53:32 2016 -0700
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: XMLErrorResources.java,v 1.2.4.1 2005/09/15 07:45:37 suresh_emailid Exp $
- */
package com.sun.org.apache.xml.internal.res;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/DOMSerializerImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
+import com.sun.org.apache.xerces.internal.dom.AbortException;
import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl;
@@ -501,11 +502,9 @@
} catch (LSException lse) {
// Rethrow LSException.
throw lse;
+ } catch (AbortException e) {
+ return null;
} catch (RuntimeException e) {
- if (e == DOMNormalizer.abort) {
- // stopped at user request
- return null;
- }
throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
} catch (IOException ioe) {
// REVISIT: A generic IOException doesn't provide enough information
@@ -733,11 +732,9 @@
} catch (LSException lse) {
// Rethrow LSException.
throw lse;
+ } catch (AbortException e) {
+ return false;
} catch (RuntimeException e) {
- if (e == DOMNormalizer.abort) {
- // stopped at user request
- return false;
- }
throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
} catch (Exception e) {
if (ser.fDOMErrorHandler != null) {
@@ -833,11 +830,9 @@
} catch (LSException lse) {
// Rethrow LSException.
throw lse;
+ } catch (AbortException e) {
+ return false;
} catch (RuntimeException e) {
- if (e == DOMNormalizer.abort) {
- // stopped at user request
- return false;
- }
throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
} catch (Exception e) {
if (ser.fDOMErrorHandler != null) {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SerializerMessages.java Mon Aug 29 08:53:32 2016 -0700
@@ -19,9 +19,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: SerializerMessages.java,v 1.1.4.1 2005/09/08 11:03:11 suresh_emailid Exp $
- */
package com.sun.org.apache.xml.internal.serializer.utils;
import java.util.ListResourceBundle;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xpath.internal.axes.LocPathIterator;
import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
import java.io.IOException;
@@ -73,6 +74,12 @@
XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
+ if (contextItem == null && xpath.getExpression() instanceof LocPathIterator) {
+ // the operation must have no dependency on the context that is null
+ throw new TransformerException(XSLMessages.createXPATHMessage(
+ XPATHErrorResources.ER_CONTEXT_CAN_NOT_BE_NULL,
+ new Object[] {}));
+ }
if (functionResolver != null) {
JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
functionResolver, featureSecureProcessing, featureManager);
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java Mon Aug 29 08:53:32 2016 -0700
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: XPATHErrorResources.java,v 1.2.4.1 2005/09/15 01:29:15 jeffsuttor Exp $
- */
package com.sun.org.apache.xpath.internal.res;
import java.util.ListResourceBundle;
@@ -93,6 +90,7 @@
public static final String ER_CURRENT_TAKES_NO_ARGS =
"ER_CURRENT_TAKES_NO_ARGS";
public static final String ER_DOCUMENT_REPLACED = "ER_DOCUMENT_REPLACED";
+ public static final String ER_CONTEXT_CAN_NOT_BE_NULL = "ER_CONTEXT_CAN_NOT_BE_NULL";
public static final String ER_CONTEXT_HAS_NO_OWNERDOC =
"ER_CONTEXT_HAS_NO_OWNERDOC";
public static final String ER_LOCALNAME_HAS_TOO_MANY_ARGS =
@@ -368,6 +366,9 @@
{ ER_DOCUMENT_REPLACED,
"document() function implementation has been replaced by com.sun.org.apache.xalan.internal.xslt.FuncDocument!"},
+ { ER_CONTEXT_CAN_NOT_BE_NULL,
+ "The context can not be null when the operation is context-dependent."},
+
{ ER_CONTEXT_HAS_NO_OWNERDOC,
"context does not have an owner document!"},
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,18 +34,20 @@
*
* <a name="XPath-evaluation"></a>
* <table border="1" cellpadding="2">
- * <thead>
- * <tr>
- * <th colspan="2">Evaluation of XPath Expressions.</th>
- * </tr>
- * </thead>
- * <tr>
- * <td>context</td>
- * <td>
- * If a request is made to evaluate the expression in the absence
- * of a context item, an empty document node will be used for the context.
- * For the purposes of evaluating XPath expressions, a DocumentFragment
- * is treated like a Document node.
+ * <thead>
+ * <tr>
+ * <th colspan="2">Evaluation of XPath Expressions.</th>
+ * </tr>
+ * </thead>
+ * <tr>
+ * <td>context</td>
+ * <td>
+ * The type of the context is implementation-dependent. If the value is
+ * null, the operation must have no dependency on the context, otherwise
+ * an XPathExpressionException will be thrown.
+ *
+ * For the purposes of evaluating XPath expressions, a DocumentFragment
+ * is treated like a Document node.
* </td>
* </tr>
* <tr>
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,19 +33,20 @@
*
* <a name="XPathExpression-evaluation"></a>
* <table border="1" cellpadding="2">
- * <thead>
- * <tr>
- * <th colspan="2">Evaluation of XPath Expressions.</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td>context</td>
- * <td>
- * If a request is made to evaluate the expression in the absence
- * of a context item, an empty document node will be used for the context.
- * For the purposes of evaluating XPath expressions, a DocumentFragment
- * is treated like a Document node.
+ * <thead>
+ * <tr>
+ * <th colspan="2">Evaluation of XPath Expressions.</th>
+ * </tr>
+ * </thead>
+ * <tr>
+ * <td>context</td>
+ * <td>
+ * The type of the context is implementation-dependent. If the value is
+ * null, the operation must have no dependency on the context, otherwise
+ * an XPathExpressionException will be thrown.
+ *
+ * For the purposes of evaluating XPath expressions, a DocumentFragment
+ * is treated like a Document node.
* </td>
* </tr>
* <tr>
--- a/jaxp/src/java.xml/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,10 @@
* questions.
*/
+/**
+ * Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX),
+ * the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API.
+ */
module java.xml {
exports javax.xml;
exports javax.xml.catalog;
--- a/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/xpath/XPathTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,11 +24,17 @@
package xpath;
import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
-
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
/*
* @test
@@ -36,19 +42,105 @@
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true xpath.XPathTest
* @run testng/othervm xpath.XPathTest
- * @summary Test XPath.getNamespaceContext() is supported.
+ * @summary Test XPath functions. See details for each test.
*/
@Listeners({jaxp.library.BasePolicy.class})
public class XPathTest {
+ /*
+ @bug 6211561
+ * Verifies the specification for XPath and XPathExpression:
+ * If a null value is provided for item (the context),
+ * the expression must have no dependency on the context.
+ */
+ @Test(dataProvider = "noContextDependency")
+ public void testNoContextDependency1(String expression, Object item) throws XPathExpressionException {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ xPath.evaluate(expression, item, XPathConstants.STRING);
+ }
+
+ @Test(dataProvider = "noContextDependency")
+ public void testNoContextDependency2(String expression, Object item) throws XPathExpressionException {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ xPath.evaluateExpression(expression, item, String.class);
+ }
+
+ /*
+ @bug 6211561
+ * Verifies the specification for XPath and XPathExpression:
+ * If a null value is provided for item (the context) that the operation
+ * depends on, XPathExpressionException will be thrown
+ */
+ @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class)
+ public void testHasContextDependency1(String expression, Object item) throws XPathExpressionException {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ xPath.evaluate(expression, item, XPathConstants.STRING);
+ }
+
+ @Test(dataProvider = "hasContextDependency", expectedExceptions = XPathExpressionException.class)
+ public void testHasContextDependency2(String expression, Object item) throws XPathExpressionException {
+ XPath xPath = XPathFactory.newInstance().newXPath();
+ xPath.evaluateExpression(expression, item, String.class);
+ }
+
+ /*
+ @bug 6376058
+ Verifies that XPath.getNamespaceContext() is supported.
+ */
@Test
public void testNamespaceContext() {
-
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
+ NamespaceContext namespaceContext = xPath.getNamespaceContext();
+ }
- NamespaceContext namespaceContext = xPath.getNamespaceContext();
+ /*
+ * DataProvider: the expression has no dependency on the context
+ */
+ @DataProvider(name = "noContextDependency")
+ public Object[][] getExpressionContext() throws Exception {
+ return new Object[][]{
+ {"1+1", (Node)null},
+ {"5 mod 2", (Node)null},
+ {"8 div 2", (Node)null},
+ {"/node", getEmptyDocument()}
+ };
+ }
+ /*
+ * DataProvider: the expression has dependency on the context, but the context
+ * is null.
+ */
+ @DataProvider(name = "hasContextDependency")
+ public Object[][] getExpressionContext1() throws Exception {
+ return new Object[][]{
+ {"/node", (Node)null},
+ {"//@lang", (Node)null},
+ {"bookstore//book", (Node)null},
+ {"/bookstore/book[last()]", (Node)null},
+ {"//title[@lang='en']", (Node)null},
+ {"/bookstore/book[price>9.99]", (Node)null},
+ {"/bookstore/book[price>8.99 and price<9.99]", (Node)null},
+ {"/bookstore/*", (Node)null},
+ {"//title[@*]", (Node)null},
+ {"//title | //price", (Node)null},
+ {"//book/title | //book/price", (Node)null},
+ {"/bookstore/book/title | //price", (Node)null},
+ {"child::book", (Node)null},
+ {"child::text()", (Node)null},
+ {"child::*/child::price", (Node)null}
+ };
+ }
+
+ /**
+ * Returns an empty {@link org.w3c.dom.Document}.
+ * @return a DOM Document, null in case of Exception
+ */
+ public Document getEmptyDocument() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ } catch (ParserConfigurationException e) {
+ return null;
+ }
}
}
-
--- a/jaxws/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxws/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -377,3 +377,4 @@
46a02f57218e4a8c334dbccf656fb048f823f163 jdk-9+129
39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130
783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131
+9fff2477a4cadf2a9618a76f1f4fe0f20bb5ff3b jdk-9+132
--- a/jaxws/src/java.activation/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxws/src/java.activation/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,9 @@
* questions.
*/
+/**
+ * Defines the JavaBeans Activation Framework (JAF) API.
+ */
module java.activation {
requires public java.datatransfer;
// dependence on java.beans.Beans to be eliminated
--- a/jaxws/src/java.annotations.common/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxws/src/java.annotations.common/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,10 @@
* questions.
*/
+/**
+ * Defines a subset of the Common Annotations API to support programs running
+ * on the Java SE Platform.
+ */
module java.annotations.common {
exports javax.annotation;
}
--- a/jaxws/src/java.xml.bind/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxws/src/java.xml.bind/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,9 @@
* questions.
*/
+/**
+ * Defines the Java Architecture for XML Binding (JAXB) API.
+ */
module java.xml.bind {
requires public java.activation;
requires public java.xml;
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jaxws/src/java.xml.ws/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,10 @@
* questions.
*/
+/**
+ * Defines the Java API for XML-Based Web Services (JAX-WS), and
+ * the Web Services Metadata API.
+ */
module java.xml.ws {
requires public java.activation;
requires public java.xml;
--- a/jdk/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -375,3 +375,4 @@
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
+3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133
--- a/jdk/make/data/cryptopolicy/limited/default_local.policy Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-// Some countries have import limits on crypto strength. This policy file
-// is worldwide importable.
-
-grant {
- permission javax.crypto.CryptoPermission "DES", 64;
- permission javax.crypto.CryptoPermission "DESede", *;
- permission javax.crypto.CryptoPermission "RC2", 128,
- "javax.crypto.spec.RC2ParameterSpec", 128;
- permission javax.crypto.CryptoPermission "RC4", 128;
- permission javax.crypto.CryptoPermission "RC5", 128,
- "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
- permission javax.crypto.CryptoPermission "RSA", *;
- permission javax.crypto.CryptoPermission *, 128;
-};
--- a/jdk/make/data/cryptopolicy/limited/exempt_local.policy Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-// Some countries have import limits on crypto strength. So this file
-// will be useful.
-
-grant {
- // There is no restriction to any algorithms if KeyRecovery is enforced.
- permission javax.crypto.CryptoPermission *, "KeyRecovery";
-
- // There is no restriction to any algorithms if KeyEscrow is enforced.
- permission javax.crypto.CryptoPermission *, "KeyEscrow";
-
- // There is no restriction to any algorithms if KeyWeakening is enforced.
- permission javax.crypto.CryptoPermission *, "KeyWeakening";
-};
--- a/jdk/make/data/cryptopolicy/unlimited/default_US_export.policy Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// Manufacturing policy file.
-grant {
- // There is no restriction to any algorithms.
- permission javax.crypto.CryptoAllPermission;
-};
--- a/jdk/make/data/cryptopolicy/unlimited/default_local.policy Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-// Country-specific policy file for countries with no limits on crypto strength.
-grant {
- // There is no restriction to any algorithms.
- permission javax.crypto.CryptoAllPermission;
-};
--- a/jdk/make/gendata/Gendata-java.base.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/make/gendata/Gendata-java.base.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -34,7 +34,7 @@
include GendataBlacklistedCerts.gmk
-include GendataPolicyJars.gmk
+include GendataCryptoPolicy.gmk
################################################################################
@@ -64,13 +64,19 @@
GENDATA_JAVA_SECURITY_SRC := $(JDK_TOPDIR)/src/java.base/share/conf/security/java.security
GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/java.security
+ifeq ($(UNLIMITED_CRYPTO), true)
+ CRYPTO.POLICY := unlimited
+else
+ CRYPTO.POLICY := limited
+endif
+
# RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
$(call LogInfo, Generating java.security)
$(call MakeDir, $(@D))
$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
- $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
+ $(OPENJDK_TARGET_CPU_ARCH) $(CRYPTO.POLICY) $(RESTRICTED_PKGS_SRC)
TARGETS += $(GENDATA_JAVA_SECURITY)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gendata/GendataCryptoPolicy.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# In pre-JDK9 releases, Oracle JDK has had a separately downloadable set
+# of policy files which has been a nightmare for deployment.
+#
+# We now create 2 complete initial sets of policy files and package into
+# 2 different directories. The crypto.policy Security property will select
+# the active policy.
+#
+# It will be up to the user/deployer to make an informed choice
+# as to whether they are legally entitled to use the unlimited policy
+# file in their environment. The $(UNLIMITED_CRYPTO) make variable
+# determines the default directory/policy.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+
+################################################################################
+POLICY_DIR := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/policy
+LIMITED_POLICY_DIR := $(POLICY_DIR)/limited
+UNLIMITED_POLICY_DIR := $(POLICY_DIR)/unlimited
+
+POLICY_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/conf/security/policy
+LIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/limited
+UNLIMITED_POLICY_SRC_DIR := $(POLICY_SRC_DIR)/unlimited
+
+$(POLICY_DIR)/README.txt: $(POLICY_SRC_DIR)/README.txt
+ $(install-file)
+
+$(LIMITED_POLICY_DIR)/%: $(LIMITED_POLICY_SRC_DIR)/%
+ $(install-file)
+
+$(UNLIMITED_POLICY_DIR)/%: $(UNLIMITED_POLICY_SRC_DIR)/%
+ $(install-file)
+
+TARGETS += \
+ $(POLICY_DIR)/README.txt \
+ $(LIMITED_POLICY_DIR)/default_US_export.policy \
+ $(LIMITED_POLICY_DIR)/default_local.policy \
+ $(LIMITED_POLICY_DIR)/exempt_local.policy \
+ $(UNLIMITED_POLICY_DIR)/default_US_export.policy \
+ $(UNLIMITED_POLICY_DIR)/default_local.policy \
+
+################################################################################
--- a/jdk/make/gendata/GendataPolicyJars.gmk Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-#
-# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-include $(SPEC)
-include MakeBase.gmk
-include JarArchive.gmk
-
-
-################################################################################
-
-US_EXPORT_POLICY_JAR_DST := \
- $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar
-
-US_EXPORT_POLICY_JAR_LIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar
-US_EXPORT_POLICY_JAR_UNLIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar
-
-#
-# TODO fix so that SetupJarArchive does not write files into SRCS
-# then we don't need this extra copying
-#
-# NOTE: We currently do not place restrictions on our limited export
-# policy. This was not a typo. This means we are shipping the same file
-# for both limited and unlimited US_export_policy.jar. Only the local
-# policy file currently has restrictions.
-#
-US_EXPORT_POLICY_JAR_SRC_DIR := \
- $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited
-US_EXPORT_POLICY_JAR_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp
-
-$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
- $(install-file)
-
-US_EXPORT_POLICY_JAR_DEPS := \
- $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
-
-$(eval $(call SetupJarArchive, BUILD_US_EXPORT_POLICY_JAR, \
- DEPENDENCIES := $(US_EXPORT_POLICY_JAR_DEPS), \
- SRCS := $(US_EXPORT_POLICY_JAR_TMP), \
- SUFFIXES := .policy, \
- JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
- SKIP_METAINF := true, \
-))
-
-$(US_EXPORT_POLICY_JAR_LIMITED): \
- $(US_EXPORT_POLICY_JAR_UNLIMITED)
- $(call LogInfo, Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@))
- $(install-file)
-
-TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED)
-
-ifeq ($(UNLIMITED_CRYPTO), true)
- $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED)
- $(install-file)
-else
- $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_LIMITED)
- $(install-file)
-endif
-
-POLICY_JARS += $(US_EXPORT_POLICY_JAR_DST)
-
-################################################################################
-
-LOCAL_POLICY_JAR_DST := \
- $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar
-
-LOCAL_POLICY_JAR_LIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar
-LOCAL_POLICY_JAR_UNLIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar
-
-#
-# TODO fix so that SetupJarArchive does not write files into SRCS
-# then we don't need this extra copying
-#
-LOCAL_POLICY_JAR_LIMITED_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp
-LOCAL_POLICY_JAR_UNLIMITED_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp
-
-$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \
- $(JDK_TOPDIR)/make/data/cryptopolicy/limited/%
- $(install-file)
-
-$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \
- $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/%
- $(install-file)
-
-$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_LIMITED, \
- DEPENDENCIES := $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \
- $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \
- SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \
- SUFFIXES := .policy, \
- JAR := $(LOCAL_POLICY_JAR_LIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \
- SKIP_METAINF := true, \
-))
-
-$(eval $(call SetupJarArchive, BUILD_LOCAL_POLICY_JAR_UNLIMITED, \
- DEPENDENCIES := $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \
- SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \
- SUFFIXES := .policy, \
- JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
- SKIP_METAINF := true, \
-))
-
-TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED)
-
-ifeq ($(UNLIMITED_CRYPTO), true)
- $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNLIMITED)
- $(install-file)
-else
- $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_LIMITED)
- $(install-file)
-endif
-
-POLICY_JARS += $(LOCAL_POLICY_JAR_DST)
-TARGETS += $(POLICY_JARS)
-
-################################################################################
-
-$(eval $(call IncludeCustomExtension, jdk, gendata/GendataPolicyJars.gmk))
--- a/jdk/make/launcher/Launcher-jdk.jdeps.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/make/launcher/Launcher-jdk.jdeps.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -36,3 +36,9 @@
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
))
+
+$(eval $(call SetupBuildLauncher, jdeprscan, \
+ MAIN_CLASS := com.sun.tools.jdeprscan.Main, \
+ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
+ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
+))
--- a/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -38,8 +38,6 @@
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
$(LIBJAVA_HEADER_FLAGS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
- DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
- DISABLED_WARNINGS_microsoft := 4013 4267, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
--- a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,8 @@
*
* 1. Adds additional packages to the package.access and
* package.definition security properties.
- * 2. Filter out platform-unrelated parts
+ * 2. Filter out platform-unrelated parts.
+ * 3. Set the JCE jurisdiction policy directory.
*
* In order to easily maintain platform-related entries, every item
* (including the last line) in package.access and package.definition
@@ -50,12 +51,13 @@
public static void main(String[] args) throws Exception {
- if (args.length < 4) {
+ if (args.length < 5) {
System.err.println("Usage: java MakeJavaSecurity " +
"[input java.security file name] " +
"[output java.security file name] " +
"[openjdk target os] " +
"[openjdk target cpu architecture]" +
+ "[JCE jurisdiction policy directory]" +
"[more restricted packages file name?]");
System.exit(1);
@@ -63,8 +65,8 @@
// more restricted packages
List<String> extraLines;
- if (args.length == 5) {
- extraLines = Files.readAllLines(Paths.get(args[4]));
+ if (args.length == 6) {
+ extraLines = Files.readAllLines(Paths.get(args[5]));
} else {
extraLines = Collections.emptyList();
}
@@ -135,6 +137,16 @@
}
}
+ // Set the JCE policy value
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines.get(i);
+ int index = line.indexOf("crypto.policydir-tbd");
+ if (index >= 0) {
+ String prefix = line.substring(0, index);
+ lines.set(i, prefix + args[4]);
+ }
+ }
+
// Clean up the last line of PKG_ACC and PKG_DEF blocks.
// Not really necessary since a blank line follows.
boolean inBlock = false;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java Mon Aug 29 08:53:32 2016 -0700
@@ -986,8 +986,9 @@
if (padding != null) {
int padStart = padding.unpad(outWithPadding, 0, outLen);
if (padStart < 0) {
- throw new BadPaddingException("Given final block not "
- + "properly padded");
+ throw new BadPaddingException("Given final block not " +
+ "properly padded. Such issues can arise if a bad key " +
+ "is used during decryption.");
}
outLen = padStart;
}
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Mon Aug 29 08:53:32 2016 -0700
@@ -331,12 +331,6 @@
* Note that this method does not check whether the requested class
* is accessible to its caller.
*
- * <p> If the {@code loader} is {@code null}, and a security
- * manager is present, and the caller's class loader is not null, then this
- * method calls the security manager's {@code checkPermission} method
- * with a {@code RuntimePermission("getClassLoader")} permission to
- * ensure it's ok to access the bootstrap class loader.
- *
* @param name fully qualified name of the desired class
* @param initialize if {@code true} the class will be initialized.
* See Section 12.4 of <em>The Java Language Specification</em>.
@@ -348,6 +342,11 @@
* by this method fails
* @exception ClassNotFoundException if the class cannot be located by
* the specified class loader
+ * @exception SecurityException
+ * if a security manager is present, and the {@code loader} is
+ * {@code null}, and the caller's class loader is not
+ * {@code null}, and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
*
* @see java.lang.Class#forName(String)
* @see java.lang.ClassLoader
@@ -782,22 +781,17 @@
* null in such implementations if this class was loaded by the bootstrap
* class loader.
*
- * <p> If a security manager is present, and the caller's class loader is
- * not null and the caller's class loader is not the same as or an ancestor of
- * the class loader for the class whose class loader is requested, then
- * this method calls the security manager's {@code checkPermission}
- * method with a {@code RuntimePermission("getClassLoader")}
- * permission to ensure it's ok to access the class loader for the class.
- *
* <p>If this object
* represents a primitive type or void, null is returned.
*
* @return the class loader that loaded the class or interface
* represented by this object.
- * @throws SecurityException
- * if a security manager exists and its
- * {@code checkPermission} method denies
- * access to the class loader for the class.
+ * @throws SecurityException
+ * if a security manager is present, and the caller's class loader
+ * is not {@code null} and is not the same as or an ancestor of the
+ * class loader for the class whose class loader is requested,
+ * and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
* @see java.lang.ClassLoader
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Mon Aug 29 08:53:32 2016 -0700
@@ -1537,22 +1537,13 @@
* will return <tt>null</tt> in such implementations if this class loader's
* parent is the bootstrap class loader.
*
- * <p> If a security manager is present, and the invoker's class loader is
- * not <tt>null</tt> and is not an ancestor of this class loader, then this
- * method invokes the security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission)
- * <tt>checkPermission</tt>} method with a {@link
- * RuntimePermission#RuntimePermission(String)
- * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
- * access to the parent class loader is permitted. If not, a
- * <tt>SecurityException</tt> will be thrown. </p>
- *
* @return The parent <tt>ClassLoader</tt>
*
* @throws SecurityException
- * If a security manager exists and its <tt>checkPermission</tt>
- * method doesn't allow access to this class loader's parent class
- * loader.
+ * If a security manager is present, and the caller's class loader
+ * is not {@code null} and is not an ancestor of this class loader,
+ * and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
*
* @since 1.2
*/
@@ -1590,12 +1581,11 @@
* @return The platform {@code ClassLoader}.
*
* @throws SecurityException
- * If a security manager exists and the caller's class loader is
- * not {@code null} and the caller's class loader is not the same
+ * If a security manager is present, and the caller's class loader is
+ * not {@code null}, and the caller's class loader is not the same
* as or an ancestor of the platform class loader,
- * and the {@link SecurityManager#checkPermission(java.security.Permission)
- * checkPermission} method denies {@code RuntimePermission("getClassLoader")}
- * to access the platform class loader.
+ * and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
*
* @since 9
*/
@@ -1636,17 +1626,6 @@
* If circular initialization of the system class loader is detected then
* an unspecified error or exception is thrown.
*
- * <p> If a security manager is present, and the invoker's class loader is
- * not <tt>null</tt> and the invoker's class loader is not the same as or
- * an ancestor of the system class loader, then this method invokes the
- * security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission)
- * <tt>checkPermission</tt>} method with a {@link
- * RuntimePermission#RuntimePermission(String)
- * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
- * access to the system class loader. If not, a
- * <tt>SecurityException</tt> will be thrown. </p>
- *
* @implNote The system property to override the system class loader is not
* examined until the VM is almost fully initialized. Code that executes
* this method during startup should take care not to cache the return
@@ -1656,8 +1635,10 @@
* <tt>null</tt> if none
*
* @throws SecurityException
- * If a security manager exists and its <tt>checkPermission</tt>
- * method doesn't allow access to the system class loader.
+ * If a security manager is present, and the caller's class loader
+ * is not {@code null} and is not the same as or an ancestor of the
+ * system class loader, and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
*
* @throws IllegalStateException
* If invoked recursively during the construction of the class
--- a/jdk/src/java.base/share/classes/java/lang/Math.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java Mon Aug 29 08:53:32 2016 -0700
@@ -1370,8 +1370,13 @@
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
- * In other words, the result is the same as the value of the expression:
- * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+ *
+ * @apiNote As implied by the above, one valid implementation of
+ * this method is given by the expression below which computes a
+ * {@code float} with the same exponent and significand as the
+ * argument but with a guaranteed zero sign bit indicating a
+ * positive value:<br>
+ * {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
@@ -1389,8 +1394,13 @@
* is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
- * In other words, the result is the same as the value of the expression:
- * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+ *
+ * @apiNote As implied by the above, one valid implementation of
+ * this method is given by the expression below which computes a
+ * {@code double} with the same exponent and significand as the
+ * argument but with a guaranteed zero sign bit indicating a
+ * positive value:<br>
+ * {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
--- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java Mon Aug 29 08:53:32 2016 -0700
@@ -1070,8 +1070,13 @@
* result is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
- * In other words, the result is the same as the value of the expression:
- * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+ *
+ * @apiNote As implied by the above, one valid implementation of
+ * this method is given by the expression below which computes a
+ * {@code float} with the same exponent and significand as the
+ * argument but with a guaranteed zero sign bit indicating a
+ * positive value: <br>
+ * {@code Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a))}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
@@ -1089,8 +1094,13 @@
* is positive zero.
* <li>If the argument is infinite, the result is positive infinity.
* <li>If the argument is NaN, the result is NaN.</ul>
- * In other words, the result is the same as the value of the expression:
- * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+ *
+ * @apiNote As implied by the above, one valid implementation of
+ * this method is given by the expression below which computes a
+ * {@code double} with the same exponent and significand as the
+ * argument but with a guaranteed zero sign bit indicating a
+ * positive value: <br>
+ * {@code Double.longBitsToDouble((Double.doubleToRawLongBits(a)<<1)>>>1)}
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Mon Aug 29 08:53:32 2016 -0700
@@ -1507,28 +1507,25 @@
}
/**
- * Returns the context ClassLoader for this Thread. The context
- * ClassLoader is provided by the creator of the thread for use
+ * Returns the context {@code ClassLoader} for this thread. The context
+ * {@code ClassLoader} is provided by the creator of the thread for use
* by code running in this thread when loading classes and resources.
* If not {@linkplain #setContextClassLoader set}, the default is the
- * ClassLoader context of the parent Thread. The context ClassLoader of the
+ * {@code ClassLoader} context of the parent thread. The context
+ * {@code ClassLoader} of the
* primordial thread is typically set to the class loader used to load the
* application.
*
- * <p>If a security manager is present, and the invoker's class loader is not
- * {@code null} and is not the same as or an ancestor of the context class
- * loader, then this method invokes the security manager's {@link
- * SecurityManager#checkPermission(java.security.Permission) checkPermission}
- * method with a {@link RuntimePermission RuntimePermission}{@code
- * ("getClassLoader")} permission to verify that retrieval of the context
- * class loader is permitted.
*
- * @return the context ClassLoader for this Thread, or {@code null}
+ * @return the context {@code ClassLoader} for this thread, or {@code null}
* indicating the system class loader (or, failing that, the
* bootstrap class loader)
*
* @throws SecurityException
- * if the current thread cannot get the context ClassLoader
+ * if a security manager is present, and the caller's class loader
+ * is not {@code null} and is not the same as or an ancestor of the
+ * context class loader, and the caller does not have the
+ * {@link RuntimePermission}{@code ("getClassLoader")}
*
* @since 1.2
*/
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Mon Aug 29 08:53:32 2016 -0700
@@ -497,6 +497,10 @@
String shortTypes = LambdaForm.shortenSignature(types);
String className = SPECIES_CLASS_PREFIX + shortTypes;
Class<?> c = BootLoader.loadClassOrNull(className);
+ if (TRACE_RESOLVE) {
+ System.out.println("[BMH_RESOLVE] " + shortTypes +
+ (c != null ? " (success)" : " (fail)") );
+ }
if (c != null) {
return c.asSubclass(BoundMethodHandle.class);
} else {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Aug 29 08:53:32 2016 -0700
@@ -492,7 +492,7 @@
}
// Caching machinery for field accessors:
- private static final byte
+ static final byte
AF_GETFIELD = 0,
AF_PUTFIELD = 1,
AF_GETSTATIC = 2,
@@ -502,7 +502,7 @@
AF_LIMIT = 6;
// Enumerate the different field kinds using Wrapper,
// with an extra case added for checked references.
- private static final int
+ static final int
FT_LAST_WRAPPER = Wrapper.COUNT-1,
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
@@ -515,7 +515,7 @@
@Stable
private static final LambdaForm[] ACCESSOR_FORMS
= new LambdaForm[afIndex(AF_LIMIT, false, 0)];
- private static int ftypeKind(Class<?> ftype) {
+ static int ftypeKind(Class<?> ftype) {
if (ftype.isPrimitive())
return Wrapper.forPrimitiveType(ftype).ordinal();
else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
@@ -566,7 +566,64 @@
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
- private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
+ private static Kind getFieldKind(boolean isGetter, boolean isVolatile, Wrapper wrapper) {
+ if (isGetter) {
+ if (isVolatile) {
+ switch (wrapper) {
+ case BOOLEAN: return GET_BOOLEAN_VOLATILE;
+ case BYTE: return GET_BYTE_VOLATILE;
+ case SHORT: return GET_SHORT_VOLATILE;
+ case CHAR: return GET_CHAR_VOLATILE;
+ case INT: return GET_INT_VOLATILE;
+ case LONG: return GET_LONG_VOLATILE;
+ case FLOAT: return GET_FLOAT_VOLATILE;
+ case DOUBLE: return GET_DOUBLE_VOLATILE;
+ case OBJECT: return GET_OBJECT_VOLATILE;
+ }
+ } else {
+ switch (wrapper) {
+ case BOOLEAN: return GET_BOOLEAN;
+ case BYTE: return GET_BYTE;
+ case SHORT: return GET_SHORT;
+ case CHAR: return GET_CHAR;
+ case INT: return GET_INT;
+ case LONG: return GET_LONG;
+ case FLOAT: return GET_FLOAT;
+ case DOUBLE: return GET_DOUBLE;
+ case OBJECT: return GET_OBJECT;
+ }
+ }
+ } else {
+ if (isVolatile) {
+ switch (wrapper) {
+ case BOOLEAN: return PUT_BOOLEAN_VOLATILE;
+ case BYTE: return PUT_BYTE_VOLATILE;
+ case SHORT: return PUT_SHORT_VOLATILE;
+ case CHAR: return PUT_CHAR_VOLATILE;
+ case INT: return PUT_INT_VOLATILE;
+ case LONG: return PUT_LONG_VOLATILE;
+ case FLOAT: return PUT_FLOAT_VOLATILE;
+ case DOUBLE: return PUT_DOUBLE_VOLATILE;
+ case OBJECT: return PUT_OBJECT_VOLATILE;
+ }
+ } else {
+ switch (wrapper) {
+ case BOOLEAN: return PUT_BOOLEAN;
+ case BYTE: return PUT_BYTE;
+ case SHORT: return PUT_SHORT;
+ case CHAR: return PUT_CHAR;
+ case INT: return PUT_INT;
+ case LONG: return PUT_LONG;
+ case FLOAT: return PUT_FLOAT;
+ case DOUBLE: return PUT_DOUBLE;
+ case OBJECT: return PUT_OBJECT;
+ }
+ }
+ }
+ throw new AssertionError("Invalid arguments");
+ }
+
+ static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
boolean isStatic = (formOp >= AF_GETSTATIC);
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
@@ -576,24 +633,14 @@
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
// getObject, putIntVolatile, etc.
- StringBuilder nameBuilder = new StringBuilder();
- if (isGetter) {
- nameBuilder.append("get");
- } else {
- nameBuilder.append("put");
- }
- nameBuilder.append(fw.primitiveSimpleName());
- nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
- if (isVolatile) {
- nameBuilder.append("Volatile");
- }
+ Kind kind = getFieldKind(isGetter, isVolatile, fw);
MethodType linkerType;
if (isGetter)
linkerType = MethodType.methodType(ft, Object.class, long.class);
else
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
- MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
+ MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
try {
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
} catch (ReflectiveOperationException ex) {
@@ -620,6 +667,7 @@
final int F_HOLDER = (isStatic ? nameCursor++ : -1); // static base if any
final int F_OFFSET = nameCursor++; // Either static offset or field offset.
final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
+ final int U_HOLDER = nameCursor++; // UNSAFE holder
final int INIT_BAR = (needsInit ? nameCursor++ : -1);
final int PRE_CAST = (needsCast && !isGetter ? nameCursor++ : -1);
final int LINKER_CALL = nameCursor++;
@@ -632,7 +680,7 @@
names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
Object[] outArgs = new Object[1 + linkerType.parameterCount()];
assert(outArgs.length == (isGetter ? 3 : 4));
- outArgs[0] = UNSAFE;
+ outArgs[0] = names[U_HOLDER] = new Name(NF_UNSAFE);
if (isStatic) {
outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]);
outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]);
@@ -650,6 +698,7 @@
for (Name n : names) assert(n != null);
// add some detail to the lambdaForm debugname,
// significant only for debugging
+ StringBuilder nameBuilder = new StringBuilder(kind.methodName);
if (isStatic) {
nameBuilder.append("Static");
} else {
@@ -657,7 +706,12 @@
}
if (needsCast) nameBuilder.append("Cast");
if (needsInit) nameBuilder.append("Init");
- return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
+ if (needsCast || needsInit) {
+ // can't use the pre-generated form when casting and/or initializing
+ return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
+ } else {
+ return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT, kind);
+ }
}
/**
@@ -674,7 +728,8 @@
NF_staticOffset,
NF_checkCast,
NF_allocateInstance,
- NF_constructorMethod;
+ NF_constructorMethod,
+ NF_UNSAFE;
static {
try {
NamedFunction nfs[] = {
@@ -697,7 +752,9 @@
NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
.getDeclaredMethod("allocateInstance", Object.class)),
NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
- .getDeclaredMethod("constructorMethod", Object.class))
+ .getDeclaredMethod("constructorMethod", Object.class)),
+ NF_UNSAFE = new NamedFunction(new MemberName(MethodHandleStatics.class
+ .getDeclaredField("UNSAFE")))
};
// Each nf must be statically invocable or we get tied up in our bootstraps.
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
--- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,9 +28,11 @@
import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
-
import java.util.ArrayList;
import java.util.HashSet;
+import sun.invoke.util.Wrapper;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
/**
* Helper class to assist the GenerateJLIClassesPlugin to get access to
@@ -66,14 +68,38 @@
static byte[] generateDirectMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes, int[] types) {
- LambdaForm[] forms = new LambdaForm[methodTypes.length];
- String[] names = new String[methodTypes.length];
- for (int i = 0; i < forms.length; i++) {
- forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
- types[i]);
- names[i] = forms[i].kind.defaultLambdaName;
+ ArrayList<LambdaForm> forms = new ArrayList<>();
+ ArrayList<String> names = new ArrayList<>();
+ for (int i = 0; i < methodTypes.length; i++) {
+ LambdaForm form = DirectMethodHandle
+ .makePreparedLambdaForm(methodTypes[i], types[i]);
+ forms.add(form);
+ names.add(form.kind.defaultLambdaName);
}
- return generateCodeBytesForLFs(className, names, forms);
+ for (Wrapper wrapper : Wrapper.values()) {
+ if (wrapper == Wrapper.VOID) {
+ continue;
+ }
+ for (byte b = DirectMethodHandle.AF_GETFIELD; b < DirectMethodHandle.AF_LIMIT; b++) {
+ int ftype = DirectMethodHandle.ftypeKind(wrapper.primitiveType());
+ LambdaForm form = DirectMethodHandle
+ .makePreparedFieldLambdaForm(b, /*isVolatile*/false, ftype);
+ if (form.kind != LambdaForm.Kind.GENERIC) {
+ forms.add(form);
+ names.add(form.kind.defaultLambdaName);
+ }
+ // volatile
+ form = DirectMethodHandle
+ .makePreparedFieldLambdaForm(b, /*isVolatile*/true, ftype);
+ if (form.kind != LambdaForm.Kind.GENERIC) {
+ forms.add(form);
+ names.add(form.kind.defaultLambdaName);
+ }
+ }
+ }
+ return generateCodeBytesForLFs(className,
+ names.toArray(new String[0]),
+ forms.toArray(new LambdaForm[0]));
}
static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
@@ -107,6 +133,34 @@
forms.toArray(new LambdaForm[0]));
}
+ static byte[] generateInvokersHolderClassBytes(String className,
+ MethodType[] methodTypes) {
+
+ HashSet<MethodType> dedupSet = new HashSet<>();
+ ArrayList<LambdaForm> forms = new ArrayList<>();
+ ArrayList<String> names = new ArrayList<>();
+ int[] types = {
+ MethodTypeForm.LF_EX_LINKER,
+ MethodTypeForm.LF_EX_INVOKER,
+ MethodTypeForm.LF_GEN_LINKER,
+ MethodTypeForm.LF_GEN_INVOKER
+ };
+ for (int i = 0; i < methodTypes.length; i++) {
+ // generate methods representing invokers of the specified type
+ if (dedupSet.add(methodTypes[i])) {
+ for (int type : types) {
+ LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i],
+ /*customized*/false, type);
+ forms.add(invokerForm);
+ names.add(invokerForm.kind.defaultLambdaName);
+ }
+ }
+ }
+ return generateCodeBytesForLFs(className,
+ names.toArray(new String[0]),
+ forms.toArray(new LambdaForm[0]));
+ }
+
/*
* Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name.
@@ -166,4 +220,5 @@
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
shortTypes, types, className));
}
+
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Mon Aug 29 08:53:32 2016 -0700
@@ -607,7 +607,10 @@
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
-
+ if (TRACE_RESOLVE) {
+ System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
+ shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
+ }
return resolvedMember;
}
@@ -629,6 +632,28 @@
name = name + "_" + form.returnType().basicTypeChar();
return resolveFrom(name, invokerType, LambdaForm.Holder.class);
}
+ case EXACT_INVOKER: // fall-through
+ case EXACT_LINKER: // fall-through
+ case GENERIC_INVOKER: // fall-through
+ case GENERIC_LINKER: return resolveFrom(name, invokerType.basicType(), Invokers.Holder.class);
+ case GET_OBJECT: // fall-through
+ case GET_BOOLEAN: // fall-through
+ case GET_BYTE: // fall-through
+ case GET_CHAR: // fall-through
+ case GET_SHORT: // fall-through
+ case GET_INT: // fall-through
+ case GET_LONG: // fall-through
+ case GET_FLOAT: // fall-through
+ case GET_DOUBLE: // fall-through
+ case PUT_OBJECT: // fall-through
+ case PUT_BOOLEAN: // fall-through
+ case PUT_BYTE: // fall-through
+ case PUT_CHAR: // fall-through
+ case PUT_SHORT: // fall-through
+ case PUT_INT: // fall-through
+ case PUT_LONG: // fall-through
+ case PUT_FLOAT: // fall-through
+ case PUT_DOUBLE: // fall-through
case DIRECT_INVOKE_INTERFACE: // fall-through
case DIRECT_INVOKE_SPECIAL: // fall-through
case DIRECT_INVOKE_STATIC: // fall-through
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Mon Aug 29 08:53:32 2016 -0700
@@ -36,6 +36,7 @@
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.LambdaForm.Kind.*;
/**
* Construction and caching of often-used invokers.
@@ -254,7 +255,7 @@
* @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
* 0x02 whether it is for invokeExact or generic invoke
*/
- private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
+ static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
boolean isCached;
if (!customized) {
mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
@@ -263,12 +264,12 @@
isCached = false; // maybe cache if mtype == mtype.basicType()
}
boolean isLinker, isGeneric;
- String debugName;
+ Kind kind;
switch (which) {
- case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break;
- case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
- case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break;
- case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
+ case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; kind = EXACT_LINKER; break;
+ case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; kind = EXACT_INVOKER; break;
+ case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; kind = GENERIC_LINKER; break;
+ case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; kind = GENERIC_INVOKER; break;
default: throw new InternalError();
}
LambdaForm lform;
@@ -323,7 +324,11 @@
names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
}
names[LINKER_CALL] = new Name(outCallType, outArgs);
- lform = new LambdaForm(debugName, INARG_LIMIT, names);
+ if (customized) {
+ lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names);
+ } else {
+ lform = new LambdaForm(kind.defaultLambdaName, INARG_LIMIT, names, kind);
+ }
if (isLinker)
lform.compileToBytecode(); // JVM needs a real methodOop
if (isCached)
@@ -614,4 +619,15 @@
}
}
}
+
+ static {
+ // The Holder class will contain pre-generated Invokers resolved
+ // speculatively using MemberName.getFactory().resolveOrNull. However, that
+ // doesn't initialize the class, which subtly breaks inlining etc. By forcing
+ // initialization of the Holder class we avoid these issues.
+ UNSAFE.ensureClassInitialized(Holder.class);
+ }
+
+ /* Placeholder class for Invokers generated ahead of time */
+ final class Holder {}
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Mon Aug 29 08:53:32 2016 -0700
@@ -275,12 +275,52 @@
BOUND_REINVOKER("BMH.reinvoke"),
REINVOKER("MH.reinvoke"),
DELEGATE("MH.delegate"),
+ EXACT_LINKER("MH.invokeExact_MT"),
+ EXACT_INVOKER("MH.exactInvoker"),
+ GENERIC_LINKER("MH.invoke_MT"),
+ GENERIC_INVOKER("MH.invoker"),
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
- DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit");
+ DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit"),
+ GET_OBJECT("getObject"),
+ PUT_OBJECT("putObject"),
+ GET_OBJECT_VOLATILE("getObjectVolatile"),
+ PUT_OBJECT_VOLATILE("putObjectVolatile"),
+ GET_INT("getInt"),
+ PUT_INT("putInt"),
+ GET_INT_VOLATILE("getIntVolatile"),
+ PUT_INT_VOLATILE("putIntVolatile"),
+ GET_BOOLEAN("getBoolean"),
+ PUT_BOOLEAN("putBoolean"),
+ GET_BOOLEAN_VOLATILE("getBooleanVolatile"),
+ PUT_BOOLEAN_VOLATILE("putBooleanVolatile"),
+ GET_BYTE("getByte"),
+ PUT_BYTE("putByte"),
+ GET_BYTE_VOLATILE("getByteVolatile"),
+ PUT_BYTE_VOLATILE("putByteVolatile"),
+ GET_CHAR("getChar"),
+ PUT_CHAR("putChar"),
+ GET_CHAR_VOLATILE("getCharVolatile"),
+ PUT_CHAR_VOLATILE("putCharVolatile"),
+ GET_SHORT("getShort"),
+ PUT_SHORT("putShort"),
+ GET_SHORT_VOLATILE("getShortVolatile"),
+ PUT_SHORT_VOLATILE("putShortVolatile"),
+ GET_LONG("getLong"),
+ PUT_LONG("putLong"),
+ GET_LONG_VOLATILE("getLongVolatile"),
+ PUT_LONG_VOLATILE("putLongVolatile"),
+ GET_FLOAT("getFloat"),
+ PUT_FLOAT("putFloat"),
+ GET_FLOAT_VOLATILE("getFloatVolatile"),
+ PUT_FLOAT_VOLATILE("putFloatVolatile"),
+ GET_DOUBLE("getDouble"),
+ PUT_DOUBLE("putDouble"),
+ GET_DOUBLE_VOLATILE("getDoubleVolatile"),
+ PUT_DOUBLE_VOLATILE("putDoubleVolatile");
final String defaultLambdaName;
final String methodName;
@@ -330,6 +370,10 @@
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
}
LambdaForm(String debugName,
+ int arity, Name[] names, Kind kind) {
+ this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, kind);
+ }
+ LambdaForm(String debugName,
int arity, Name[] names, boolean forceInline) {
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
}
@@ -817,54 +861,6 @@
}
}
- private static void computeInitialPreparedForms() {
- // Find all predefined invokers and associate them with canonical empty lambda forms.
- for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
- if (!m.isStatic() || !m.isPackage()) continue;
- MethodType mt = m.getMethodType();
- if (mt.parameterCount() > 0 &&
- mt.parameterType(0) == MethodHandle.class &&
- m.getName().startsWith("interpret_")) {
- String sig = null;
- assert((sig = basicTypeSignature(mt)) != null &&
- m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
- LambdaForm form = new LambdaForm(mt);
- form.vmentry = m;
- form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
- }
- }
- }
-
- // Set this false to disable use of the interpret_L methods defined in this file.
- private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true;
-
- // The following are predefined exact invokers. The system must build
- // a separate invoker for each distinct signature.
- static Object interpret_L(MethodHandle mh) throws Throwable {
- Object[] av = {mh};
- String sig = null;
- assert(argumentTypesMatch(sig = "L_L", av));
- Object res = mh.form.interpretWithArguments(av);
- assert(returnTypesMatch(sig, av, res));
- return res;
- }
- static Object interpret_L(MethodHandle mh, Object x1) throws Throwable {
- Object[] av = {mh, x1};
- String sig = null;
- assert(argumentTypesMatch(sig = "LL_L", av));
- Object res = mh.form.interpretWithArguments(av);
- assert(returnTypesMatch(sig, av, res));
- return res;
- }
- static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable {
- Object[] av = {mh, x1, x2};
- String sig = null;
- assert(argumentTypesMatch(sig = "LLL_L", av));
- Object res = mh.form.interpretWithArguments(av);
- assert(returnTypesMatch(sig, av, res));
- return res;
- }
-
// The next few routines are called only from assert expressions
// They verify that the built-in invokers process the correct raw data types.
private static boolean argumentTypesMatch(String sig, Object[] av) {
@@ -1151,113 +1147,6 @@
return super.hashCode();
}
- // Put the predefined NamedFunction invokers into the table.
- static void initializeInvokers() {
- for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
- if (!m.isStatic() || !m.isPackage()) continue;
- MethodType type = m.getMethodType();
- if (type.equals(INVOKER_METHOD_TYPE) &&
- m.getName().startsWith("invoke_")) {
- String sig = m.getName().substring("invoke_".length());
- int arity = LambdaForm.signatureArity(sig);
- MethodType srcType = MethodType.genericMethodType(arity);
- if (LambdaForm.signatureReturn(sig) == V_TYPE)
- srcType = srcType.changeReturnType(void.class);
- MethodTypeForm typeForm = srcType.form();
- typeForm.setCachedMethodHandle(MethodTypeForm.MH_NF_INV, DirectMethodHandle.make(m));
- }
- }
- }
-
- // The following are predefined NamedFunction invokers. The system must build
- // a separate invoker for each distinct signature.
- /** void return type invokers. */
- @Hidden
- static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(0, void.class, mh, a));
- mh.invokeBasic();
- return null;
- }
- @Hidden
- static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(1, void.class, mh, a));
- mh.invokeBasic(a[0]);
- return null;
- }
- @Hidden
- static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(2, void.class, mh, a));
- mh.invokeBasic(a[0], a[1]);
- return null;
- }
- @Hidden
- static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(3, void.class, mh, a));
- mh.invokeBasic(a[0], a[1], a[2]);
- return null;
- }
- @Hidden
- static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(4, void.class, mh, a));
- mh.invokeBasic(a[0], a[1], a[2], a[3]);
- return null;
- }
- @Hidden
- static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(5, void.class, mh, a));
- mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
- return null;
- }
- /** Object return type invokers. */
- @Hidden
- static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(0, mh, a));
- return mh.invokeBasic();
- }
- @Hidden
- static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(1, mh, a));
- return mh.invokeBasic(a[0]);
- }
- @Hidden
- static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(2, mh, a));
- return mh.invokeBasic(a[0], a[1]);
- }
- @Hidden
- static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(3, mh, a));
- return mh.invokeBasic(a[0], a[1], a[2]);
- }
- @Hidden
- static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(4, mh, a));
- return mh.invokeBasic(a[0], a[1], a[2], a[3]);
- }
- @Hidden
- static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable {
- assert(arityCheck(5, mh, a));
- return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
- }
- private static boolean arityCheck(int arity, MethodHandle mh, Object[] a) {
- return arityCheck(arity, Object.class, mh, a);
- }
- private static boolean arityCheck(int arity, Class<?> rtype, MethodHandle mh, Object[] a) {
- assert(a.length == arity)
- : Arrays.asList(a.length, arity);
- assert(mh.type().basicType() == MethodType.genericMethodType(arity).changeReturnType(rtype))
- : Arrays.asList(mh, rtype, arity);
- MemberName member = mh.internalMemberName();
- if (isInvokeBasic(member)) {
- assert(arity > 0);
- assert(a[0] instanceof MethodHandle);
- MethodHandle mh2 = (MethodHandle) a[0];
- assert(mh2.type().basicType() == MethodType.genericMethodType(arity-1).changeReturnType(rtype))
- : Arrays.asList(member, mh2, rtype, arity);
- }
- return true;
- }
-
static final MethodType INVOKER_METHOD_TYPE =
MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
@@ -1920,12 +1809,7 @@
DEBUG_NAME_COUNTERS = null;
}
- // Put this last, so that previous static inits can run before.
static {
- if (USE_PREDEFINED_INTERPRET_METHODS)
- computeInitialPreparedForms();
- NamedFunction.initializeInvokers();
-
// The Holder class will contain pre-generated forms resolved
// using MemberName.getFactory(). However, that doesn't initialize the
// class, which subtly breaks inlining etc. By forcing
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -1745,6 +1745,13 @@
return GenerateJLIClassesHelper
.generateBasicFormsClassBytes(className);
}
+
+ @Override
+ public byte[] generateInvokersHolderClassBytes(final String className,
+ MethodType[] methodTypes) {
+ return GenerateJLIClassesHelper
+ .generateInvokersHolderClassBytes(className, methodTypes);
+ }
});
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Mon Aug 29 08:53:32 2016 -0700
@@ -46,6 +46,7 @@
static final boolean DUMP_CLASS_FILES;
static final boolean TRACE_INTERPRETER;
static final boolean TRACE_METHOD_LINKAGE;
+ static final boolean TRACE_RESOLVE;
static final int COMPILE_THRESHOLD;
static final boolean LOG_LF_COMPILATION_FAILURE;
static final int DONT_INLINE_THRESHOLD;
@@ -65,6 +66,8 @@
props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
+ TRACE_RESOLVE = Boolean.parseBoolean(
+ props.getProperty("java.lang.invoke.MethodHandle.TRACE_RESOLVE"));
COMPILE_THRESHOLD = Integer.parseInt(
props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean(
--- a/jdk/src/java.base/share/classes/java/net/HttpCookie.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/HttpCookie.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -233,7 +233,7 @@
// if not specify max-age, this cookie should be
// discarded when user agent is to be closed, but
// it is not expired.
- if (maxAge == MAX_AGE_UNSPECIFIED) return false;
+ if (maxAge < 0) return false;
long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
if (deltaSecond > maxAge)
@@ -952,7 +952,8 @@
String attrName,
String attrValue) {
if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
- cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue));
+ long delta = cookie.expiryDate2DeltaSeconds(attrValue);
+ cookie.setMaxAge(delta > 0 ? delta : 0);
}
}
});
--- a/jdk/src/java.base/share/classes/java/time/Duration.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java Mon Aug 29 08:53:32 2016 -0700
@@ -150,10 +150,12 @@
/**
* The pattern for parsing.
*/
- private static final Pattern PATTERN =
+ private static class Lazy {
+ static final Pattern PATTERN =
Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)D)?" +
"(T(?:([-+]?[0-9]+)H)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)(?:[.,]([0-9]{0,9}))?S)?)?",
Pattern.CASE_INSENSITIVE);
+ }
/**
* The number of seconds in the duration.
@@ -387,7 +389,7 @@
*/
public static Duration parse(CharSequence text) {
Objects.requireNonNull(text, "text");
- Matcher matcher = PATTERN.matcher(text);
+ Matcher matcher = Lazy.PATTERN.matcher(text);
if (matcher.matches()) {
// check for letter T but no time sections
if (!charMatch(text, matcher.start(3), matcher.end(3), 'T')) {
--- a/jdk/src/java.base/share/classes/java/time/ZoneOffset.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/time/ZoneOffset.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -375,15 +375,15 @@
} else if ((minutes > 0 && seconds < 0) || (minutes < 0 && seconds > 0)) {
throw new DateTimeException("Zone offset minutes and seconds must have the same sign");
}
- if (Math.abs(minutes) > 59) {
- throw new DateTimeException("Zone offset minutes not in valid range: abs(value) " +
- Math.abs(minutes) + " is not in the range 0 to 59");
+ if (minutes < -59 || minutes > 59) {
+ throw new DateTimeException("Zone offset minutes not in valid range: value " +
+ minutes + " is not in the range -59 to 59");
}
- if (Math.abs(seconds) > 59) {
- throw new DateTimeException("Zone offset seconds not in valid range: abs(value) " +
- Math.abs(seconds) + " is not in the range 0 to 59");
+ if (seconds < -59 || seconds > 59) {
+ throw new DateTimeException("Zone offset seconds not in valid range: value " +
+ seconds + " is not in the range -59 to 59");
}
- if (Math.abs(hours) == 18 && (Math.abs(minutes) > 0 || Math.abs(seconds) > 0)) {
+ if (Math.abs(hours) == 18 && (minutes | seconds) != 0) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
}
}
@@ -411,7 +411,7 @@
* @throws DateTimeException if the offset is not in the required range
*/
public static ZoneOffset ofTotalSeconds(int totalSeconds) {
- if (Math.abs(totalSeconds) > MAX_SECONDS) {
+ if (totalSeconds < -MAX_SECONDS || totalSeconds > MAX_SECONDS) {
throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00");
}
if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) {
@@ -696,11 +696,12 @@
* The comparison is "consistent with equals", as defined by {@link Comparable}.
*
* @param other the other date to compare to, not null
- * @return the comparator value, negative if less, postive if greater
+ * @return the comparator value, negative if less, positive if greater
* @throws NullPointerException if {@code other} is null
*/
@Override
public int compareTo(ZoneOffset other) {
+ // abs(totalSeconds) <= MAX_SECONDS, so no overflow can happen here
return other.totalSeconds - totalSeconds;
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Mon Aug 29 08:53:32 2016 -0700
@@ -4566,7 +4566,10 @@
boolean modified = false;
// Use (c instanceof Set) as a hint that lookup in c is as
// efficient as this view
- if (c instanceof Set<?> && c.size() > map.table.length) {
+ Node<K,V>[] t;
+ if ((t = map.table) == null) {
+ return false;
+ } else if (c instanceof Set<?> && c.size() > t.length) {
for (Iterator<?> it = iterator(); it.hasNext(); ) {
if (c.contains(it.next())) {
it.remove();
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java Mon Aug 29 08:53:32 2016 -0700
@@ -353,7 +353,7 @@
if (isMultiRelease) {
return true;
}
- if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
+ if (MULTI_RELEASE_ENABLED) {
try {
checkForSpecialAttributes();
} catch (IOException io) {
@@ -644,7 +644,7 @@
return signers == null ? null : signers.clone();
}
JarFileEntry realEntry() {
- if (isMultiRelease()) {
+ if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) {
String entryName = super.getName();
return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
}
@@ -960,7 +960,7 @@
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
CLASSPATH_LASTOCC) != -1;
// is this a multi-release jar file
- if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
+ if (MULTI_RELEASE_ENABLED) {
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
if (i != -1) {
i += MULTIRELEASE_CHARS.length;
--- a/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,6 +29,7 @@
import java.util.jar.*;
import java.io.*;
import java.net.URL;
+import java.nio.file.*;
import java.security.*;
import java.security.Provider.Service;
@@ -206,7 +207,7 @@
static {
try {
- NULL_URL = new URL("http://null.sun.com/");
+ NULL_URL = new URL("http://null.oracle.com/");
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -243,83 +244,94 @@
}
}
+ // This is called from within an doPrivileged block.
private static void setupJurisdictionPolicies() throws Exception {
- String javaHomeDir = System.getProperty("java.home");
- String sep = File.separator;
- String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
- "security" + sep;
+
+ // Sanity check the crypto.policy Security property. Single
+ // directory entry, no pseudo-directories (".", "..", leading/trailing
+ // path separators). normalize()/getParent() will help later.
+ String cryptoPolicyProperty = Security.getProperty("crypto.policy");
+ Path cpPath = Paths.get(cryptoPolicyProperty);
+
+ if ((cryptoPolicyProperty == null) ||
+ (cpPath.getNameCount() != 1) ||
+ (cpPath.compareTo(cpPath.getFileName()) != 0)) {
+ throw new SecurityException(
+ "Invalid policy directory name format: " +
+ cryptoPolicyProperty);
+ }
- File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
- File importJar = new File(pathToPolicyJar, "local_policy.jar");
+ // Prepend java.home to get the full path. normalize() in
+ // case an extra "." or ".." snuck in somehow.
+ String javaHomeProperty = System.getProperty("java.home");
+ Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
+ "security", "policy").normalize();
+ Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
+ "policy", cryptoPolicyProperty).normalize();
- if (!exportJar.exists() || !importJar.exists()) {
- throw new SecurityException
- ("Cannot locate policy or framework files!");
+ if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
+ throw new SecurityException(
+ "Invalid cryptographic jurisdiction policy directory path: " +
+ cryptoPolicyProperty);
+ }
+
+ if (!Files.isDirectory(cryptoPolicyPath)
+ || !Files.isReadable(cryptoPolicyPath)) {
+ throw new SecurityException(
+ "Can't read cryptographic policy directory: " +
+ cryptoPolicyProperty);
}
- // Read jurisdiction policies.
- CryptoPermissions defaultExport = new CryptoPermissions();
- CryptoPermissions exemptExport = new CryptoPermissions();
- loadPolicies(exportJar, defaultExport, exemptExport);
-
- CryptoPermissions defaultImport = new CryptoPermissions();
- CryptoPermissions exemptImport = new CryptoPermissions();
- loadPolicies(importJar, defaultImport, exemptImport);
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(
+ cryptoPolicyPath, "{default,exempt}_*.policy")) {
+ for (Path entry : stream) {
+ try (InputStream is = new BufferedInputStream(
+ Files.newInputStream(entry))) {
+ String filename = entry.getFileName().toString();
- // Merge the export and import policies for default applications.
- if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
- throw new SecurityException("Missing mandatory jurisdiction " +
- "policy files");
- }
- defaultPolicy = defaultExport.getMinimum(defaultImport);
-
- // Merge the export and import policies for exempt applications.
- if (exemptExport.isEmpty()) {
- exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
- } else {
- exemptPolicy = exemptExport.getMinimum(exemptImport);
- }
- }
+ CryptoPermissions tmpPerms = new CryptoPermissions();
+ tmpPerms.load(is);
- /**
- * Load the policies from the specified file. Also checks that the
- * policies are correctly signed.
- */
- private static void loadPolicies(File jarPathName,
- CryptoPermissions defaultPolicy,
- CryptoPermissions exemptPolicy)
- throws Exception {
-
- JarFile jf = new JarFile(jarPathName);
-
- Enumeration<JarEntry> entries = jf.entries();
- while (entries.hasMoreElements()) {
- JarEntry je = entries.nextElement();
- InputStream is = null;
- try {
- if (je.getName().startsWith("default_")) {
- is = jf.getInputStream(je);
- defaultPolicy.load(is);
- } else if (je.getName().startsWith("exempt_")) {
- is = jf.getInputStream(je);
- exemptPolicy.load(is);
- } else {
- continue;
- }
- } finally {
- if (is != null) {
- is.close();
+ if (filename.startsWith("default_")) {
+ // Did we find a default perms?
+ defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
+ defaultPolicy.getMinimum(tmpPerms));
+ } else if (filename.startsWith("exempt_")) {
+ // Did we find a exempt perms?
+ exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
+ exemptPolicy.getMinimum(tmpPerms));
+ } else {
+ // This should never happen. newDirectoryStream
+ // should only throw return "{default,exempt}_*.policy"
+ throw new SecurityException(
+ "Unexpected jurisdiction policy files in : " +
+ cryptoPolicyProperty);
+ }
+ } catch (Exception e) {
+ throw new SecurityException(
+ "Couldn't parse jurisdiction policy files in: " +
+ cryptoPolicyProperty);
}
}
+ } catch (DirectoryIteratorException ex) {
+ // I/O error encountered during the iteration,
+ // the cause is an IOException
+ throw new SecurityException(
+ "Couldn't iterate through the jurisdiction policy files: " +
+ cryptoPolicyProperty);
+ }
- // Enforce the signer restraint, i.e. signer of JCE framework
- // jar should also be the signer of the two jurisdiction policy
- // jar files.
- ProviderVerifier.verifyPolicySigned(je.getCertificates());
+ // Must have a default policy
+ if ((defaultPolicy == null) || defaultPolicy.isEmpty()) {
+ throw new SecurityException(
+ "Missing mandatory jurisdiction policy files: " +
+ cryptoPolicyProperty);
}
- // Close and nullify the JarFile reference to help GC.
- jf.close();
- jf = null;
+
+ // If there was an empty exempt policy file, ignore it.
+ if ((exemptPolicy != null) && exemptPolicy.isEmpty()) {
+ exemptPolicy = null;
+ }
}
static CryptoPermissions getDefaultPolicy() {
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Mon Aug 29 08:53:32 2016 -0700
@@ -46,7 +46,7 @@
boolean isNative(Object mname);
/**
- * Returns a {@code byte[]} containing the bytecode for a class implementing
+ * Returns a {@code byte[]} representation of a class implementing
* DirectMethodHandle of each pairwise combination of {@code MethodType} and
* an {@code int} representing method type. Used by
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
@@ -55,7 +55,7 @@
MethodType[] methodTypes, int[] types);
/**
- * Returns a {@code byte[]} containing the bytecode for a class implementing
+ * Returns a {@code byte[]} representation of a class implementing
* DelegatingMethodHandles of each {@code MethodType} kind in the
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
* generate such a class during the jlink phase.
@@ -64,7 +64,7 @@
MethodType[] methodTypes);
/**
- * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
+ * Returns a {@code byte[]} representation of {@code BoundMethodHandle}
* species class implementing the signature defined by {@code types}. Used
* by GenerateBMHClassesPlugin to enable generation of such classes during
* the jlink phase. Should do some added validation since this string may be
@@ -74,8 +74,15 @@
final String types);
/**
- * Returns a {@code byte[]} containing the bytecode for a class implementing
+ * Returns a {@code byte[]} representation of a class implementing
* the zero and identity forms of all {@code LambdaForm.BasicType}s.
*/
byte[] generateBasicFormsClassBytes(final String className);
+
+ /**
+ * Returns a {@code byte[]} representation of a class implementing
+ * the invoker forms for the set of supplied {@code methodTypes}.
+ */
+ byte[] generateInvokersHolderClassBytes(String className,
+ MethodType[] methodTypes);
}
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAPadding.java Mon Aug 29 08:53:32 2016 -0700
@@ -253,7 +253,8 @@
public byte[] pad(byte[] data) throws BadPaddingException {
if (data.length > maxDataSize) {
throw new BadPaddingException("Data must be shorter than "
- + (maxDataSize + 1) + " bytes");
+ + (maxDataSize + 1) + " bytes but received "
+ + data.length + " bytes.");
}
switch (type) {
case PAD_NONE:
@@ -281,7 +282,9 @@
*/
public byte[] unpad(byte[] padded) throws BadPaddingException {
if (padded.length != paddedSize) {
- throw new BadPaddingException("Decryption error");
+ throw new BadPaddingException("Decryption error." +
+ "The padded array length (" + padded.length +
+ ") is not the specified padded size (" + paddedSize + ")");
}
switch (type) {
case PAD_NONE:
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Mon Aug 29 08:53:32 2016 -0700
@@ -493,7 +493,9 @@
if (protocolVersion.useTLS11PlusSpec()) {
if (newLen < blockSize) {
- throw new BadPaddingException("invalid explicit IV");
+ throw new BadPaddingException("The length after " +
+ "padding removal (" + newLen + ") should be larger " +
+ "than <" + blockSize + "> since explicit IV used");
}
}
}
@@ -504,7 +506,6 @@
}
}
-
/*
* Decrypts a block of data, returning the size of the
* resulting block if padding was required. position and limit
@@ -575,7 +576,9 @@
// check the explicit IV of TLS v1.1 or later
if (protocolVersion.useTLS11PlusSpec()) {
if (newLen < blockSize) {
- throw new BadPaddingException("invalid explicit IV");
+ throw new BadPaddingException("The length after " +
+ "padding removal (" + newLen + ") should be larger " +
+ "than <" + blockSize + "> since explicit IV used");
}
// reset the position to the end of the decrypted data
@@ -756,7 +759,9 @@
// so accept that as well
// v3 does not require any particular value for the other bytes
if (padLen > blockSize) {
- throw new BadPaddingException("Invalid SSLv3 padding");
+ throw new BadPaddingException("Padding length (" +
+ padLen + ") of SSLv3 message should not be bigger " +
+ "than the block size (" + blockSize + ")");
}
}
return newLen;
@@ -802,7 +807,9 @@
// so accept that as well
// v3 does not require any particular value for the other bytes
if (padLen > blockSize) {
- throw new BadPaddingException("Invalid SSLv3 padding");
+ throw new BadPaddingException("Padding length (" +
+ padLen + ") of SSLv3 message should not be bigger " +
+ "than the block size (" + blockSize + ")");
}
}
@@ -925,7 +932,10 @@
case AEAD_CIPHER:
if (bb.remaining() < (recordIvSize + tagSize)) {
throw new BadPaddingException(
- "invalid AEAD cipher fragment");
+ "Insufficient buffer remaining for AEAD cipher " +
+ "fragment (" + bb.remaining() + "). Needs to be " +
+ "more than or equal to IV size (" + recordIvSize +
+ ") + tag size (" + tagSize + ")");
}
// initialize the AEAD cipher for the unique IV
--- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfo.java Mon Aug 29 08:53:32 2016 -0700
@@ -27,15 +27,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.lang.ref.SoftReference;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
-import java.util.List;
-import java.util.Locale;
import java.util.Map;
-import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
@@ -80,8 +73,6 @@
private static final long ABBR_MASK = 0xf00L;
private static final int TRANSITION_NSHIFT = 12;
- private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
-
/**
* The raw GMT offset in milliseconds between this zone and GMT.
* Negative offsets are to the west of Greenwich. To obtain local
@@ -379,6 +370,7 @@
throw new IllegalArgumentException();
}
+ Gregorian gcal = CalendarSystem.getGregorianCalendar();
CalendarDate date = gcal.newCalendarDate(null);
date.setDate(year, month + 1, day);
if (gcal.validate(date) == false) {
--- a/jdk/src/java.base/share/conf/security/java.security Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/conf/security/java.security Mon Aug 29 08:53:32 2016 -0700
@@ -490,7 +490,7 @@
# property is set then those two properties are ignored.
#
# Example,
-# ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp"
+# ocsp.responderCertSubjectName=CN=OCSP Responder, O=XYZ Corp
#
# Issuer name of the OCSP responder's certificate
@@ -505,7 +505,7 @@
# property is ignored.
#
# Example,
-# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
+# ocsp.responderCertIssuerName=CN=Enterprise CA, O=XYZ Corp
#
# Serial number of the OCSP responder's certificate
@@ -803,3 +803,94 @@
# E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
# EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
# FFFFFFFF FFFFFFFF, 2}
+
+# Cryptographic Jurisdiction Policy defaults
+#
+# Due to the import control restrictions of some countries, the default
+# JCE policy files allow for strong but "limited" cryptographic key
+# lengths to be used. If your country's cryptographic regulations allow,
+# the "unlimited" strength policy files can be used instead, which contain
+# no restrictions on cryptographic strengths.
+#
+# If your country has restrictions that don't fit either "limited" or
+# "unlimited", an appropriate set of policy files should be created and
+# configured before using this distribution. The jurisdiction policy file
+# configuration must reflect the cryptographic restrictions appropriate
+# for your country.
+#
+# YOU ARE ADVISED TO CONSULT YOUR EXPORT/IMPORT CONTROL COUNSEL OR ATTORNEY
+# TO DETERMINE THE EXACT REQUIREMENTS.
+#
+# The policy files are flat text files organized into subdirectories of
+# <java-home>/conf/security/policy. Each directory contains a complete
+# set of policy files.
+#
+# The "crypto.policy" Security property controls the directory selection,
+# and thus the effective cryptographic policy.
+#
+# The default set of directories is:
+#
+# limited | unlimited
+#
+# however other directories can be created and configured.
+#
+# Within a directory, the effective policy is the combined minimum
+# permissions of the grant statements in the file(s) with the filename
+# pattern "default_*.policy". At least one grant is required. For
+# example:
+#
+# limited = Export (all) + Import (limited) = Limited
+# unlimited = Export (all) + Import (all) = Unlimited
+#
+# The effective exemption policy is the combined minimum permissions
+# of the grant statements in the file(s) with the filename pattern
+# "exempt_*.policy". Exemption grants are optional.
+#
+# limited = grants exemption permissions, by which the
+# effective policy can be circumvented.
+# e.g. KeyRecovery/Escrow/Weakening.
+#
+# Please see the JCA documentation for additional information on these
+# files and formats.
+crypto.policy=crypto.policydir-tbd
+
+#
+# The policy for the XML Signature secure validation mode. The mode is
+# enabled by setting the property "org.jcp.xml.dsig.secureValidation" to
+# true with the javax.xml.crypto.XMLCryptoContext.setProperty() method,
+# or by running the code with a SecurityManager.
+#
+# Policy:
+# Constraint {"," Constraint }
+# Constraint:
+# AlgConstraint | MaxTransformsConstraint | MaxReferencesConstraint |
+# ReferenceUriSchemeConstraint | OtherConstraint
+# AlgConstraint
+# "disallowAlg" Uri
+# MaxTransformsConstraint:
+# "maxTransforms" Integer
+# MaxReferencesConstraint:
+# "maxReferences" Integer
+# ReferenceUriSchemeConstraint:
+# "disallowReferenceUriSchemes" String { String }
+# OtherConstraint:
+# "noDuplicateIds" | "noRetrievalMethodLoops"
+#
+# For AlgConstraint, Uri is the algorithm URI String that is not allowed.
+# See the XML Signature Recommendation for more information on algorithm
+# URI Identifiers. If the MaxTransformsConstraint or MaxReferencesConstraint is
+# specified more than once, only the last entry is enforced.
+#
+# Note: This property is currently used by the JDK Reference implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+jdk.xml.dsig.secureValidationPolicy=\
+ disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
+ disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
+ disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
+ disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
+ maxTransforms 5,\
+ maxReferences 30,\
+ disallowReferenceUriSchemes file http https,\
+ noDuplicateIds,\
+ noRetrievalMethodLoops
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/README.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,35 @@
+
+ Java(TM) Cryptography Extension Policy Files
+ for the Java(TM) Platform, Standard Edition Runtime Environment
+
+ README
+------------------------------------------------------------------------
+
+
+The JCE architecture allows flexible cryptographic strength to be
+configured via the jurisdiction policy files contained within these
+directories.
+
+Due to import control restrictions of some countries, the default
+JCE policy files bundled in this Java Runtime Environment allow
+for strong but "limited" cryptographic strengths. For convenience,
+this build also contains the "unlimited strength" policy files which
+contain no restrictions on cryptographic strengths, but they must be
+specifically activated by updating the "crypto.policy" Security property
+(e.g. <java-home>/conf/security/java.security) to point to the appropriate
+directory.
+
+Each subdirectory contains a complete policy configuration, and additional
+subdirectories can be added/removed to reflect local regulations.
+
+JCE for Java SE has been through the U.S. export review process. The JCE
+framework, along with the various JCE providers that come standard with it
+(SunJCE, SunEC, SunPKCS11, SunMSCAPI, etc), is exportable from the
+United States.
+
+You are advised to consult your export/import control counsel or attorney
+to determine the exact requirements of your location, and what policy
+settings should be used.
+
+Please see The Java(TM) Cryptography Architecture (JCA) Reference
+Guide and the java.security file for more information.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/default_US_export.policy Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,6 @@
+// Default US Export policy file.
+
+grant {
+ // There is no restriction to any algorithms.
+ permission javax.crypto.CryptoAllPermission;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/default_local.policy Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,14 @@
+// Some countries have import limits on crypto strength. This policy file
+// is worldwide importable.
+
+grant {
+ permission javax.crypto.CryptoPermission "DES", 64;
+ permission javax.crypto.CryptoPermission "DESede", *;
+ permission javax.crypto.CryptoPermission "RC2", 128,
+ "javax.crypto.spec.RC2ParameterSpec", 128;
+ permission javax.crypto.CryptoPermission "RC4", 128;
+ permission javax.crypto.CryptoPermission "RC5", 128,
+ "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
+ permission javax.crypto.CryptoPermission "RSA", *;
+ permission javax.crypto.CryptoPermission *, 128;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/limited/exempt_local.policy Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,13 @@
+// Some countries have import limits on crypto strength, but may allow for
+// these exemptions if the exemption mechanism is used.
+
+grant {
+ // There is no restriction to any algorithms if KeyRecovery is enforced.
+ permission javax.crypto.CryptoPermission *, "KeyRecovery";
+
+ // There is no restriction to any algorithms if KeyEscrow is enforced.
+ permission javax.crypto.CryptoPermission *, "KeyEscrow";
+
+ // There is no restriction to any algorithms if KeyWeakening is enforced.
+ permission javax.crypto.CryptoPermission *, "KeyWeakening";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_US_export.policy Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,6 @@
+// Default US Export policy file.
+
+grant {
+ // There is no restriction to any algorithms.
+ permission javax.crypto.CryptoAllPermission;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/conf/security/policy/unlimited/default_local.policy Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,6 @@
+// Country-specific policy file for countries with no limits on crypto strength.
+
+grant {
+ // There is no restriction to any algorithms.
+ permission javax.crypto.CryptoAllPermission;
+};
--- a/jdk/src/java.base/share/lib/security/default.policy Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/share/lib/security/default.policy Mon Aug 29 08:53:32 2016 -0700
@@ -72,6 +72,8 @@
"removeProviderProperty.XMLDSig";
permission java.security.SecurityPermission
"com.sun.org.apache.xml.internal.security.register";
+ permission java.security.SecurityPermission
+ "getProperty.jdk.xml.dsig.secureValidationPolicy";
};
grant codeBase "jrt:/java.xml.ws" {
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java Mon Aug 29 08:53:32 2016 -0700
@@ -252,6 +252,21 @@
return new UnixPath(getFileSystem(), new byte[0]);
}
+
+ // return true if this path has "." or ".."
+ private boolean hasDotOrDotDot() {
+ int n = getNameCount();
+ for (int i=0; i<n; i++) {
+ byte[] bytes = getName(i).path;
+ if ((bytes.length == 1 && bytes[0] == '.'))
+ return true;
+ if ((bytes.length == 2 && bytes[0] == '.') && bytes[1] == '.') {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public UnixFileSystem getFileSystem() {
return fs;
@@ -405,80 +420,94 @@
@Override
public UnixPath relativize(Path obj) {
- UnixPath other = toUnixPath(obj);
- if (other.equals(this))
+ UnixPath child = toUnixPath(obj);
+ if (child.equals(this))
return emptyPath();
// can only relativize paths of the same type
- if (this.isAbsolute() != other.isAbsolute())
+ if (this.isAbsolute() != child.isAbsolute())
throw new IllegalArgumentException("'other' is different type of Path");
// this path is the empty path
if (this.isEmpty())
- return other;
+ return child;
- int bn = this.getNameCount();
- int cn = other.getNameCount();
+ UnixPath base = this;
+ if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
+ base = base.normalize();
+ child = child.normalize();
+ }
+
+ int baseCount = base.getNameCount();
+ int childCount = child.getNameCount();
// skip matching names
- int n = (bn > cn) ? cn : bn;
+ int n = Math.min(baseCount, childCount);
int i = 0;
while (i < n) {
- if (!this.getName(i).equals(other.getName(i)))
+ if (!base.getName(i).equals(child.getName(i)))
break;
i++;
}
- int dotdots = bn - i;
- if (i < cn) {
- // remaining name components in other
- UnixPath remainder = other.subpath(i, cn);
- if (dotdots == 0)
- return remainder;
+ // remaining elements in child
+ UnixPath childRemaining;
+ boolean isChildEmpty;
+ if (i == childCount) {
+ childRemaining = emptyPath();
+ isChildEmpty = true;
+ } else {
+ childRemaining = child.subpath(i, childCount);
+ isChildEmpty = childRemaining.isEmpty();
+ }
+
+ // matched all of base
+ if (i == baseCount) {
+ return childRemaining;
+ }
- // other is the empty path
- boolean isOtherEmpty = other.isEmpty();
+ // the remainder of base cannot contain ".."
+ UnixPath baseRemaining = base.subpath(i, baseCount);
+ if (baseRemaining.hasDotOrDotDot()) {
+ throw new IllegalArgumentException("Unable to compute relative "
+ + " path from " + this + " to " + obj);
+ }
+ if (baseRemaining.isEmpty())
+ return childRemaining;
+
+ // number of ".." needed
+ int dotdots = baseRemaining.getNameCount();
+ if (dotdots == 0) {
+ return childRemaining;
+ }
- // result is a "../" for each remaining name in base
- // followed by the remaining names in other. If the remainder is
- // the empty path then we don't add the final trailing slash.
- int len = dotdots*3 + remainder.path.length;
- if (isOtherEmpty) {
- assert remainder.isEmpty();
- len--;
+ // result is a "../" for each remaining name in base followed by the
+ // remaining names in child. If the remainder is the empty path
+ // then we don't add the final trailing slash.
+ int len = dotdots*3 + childRemaining.path.length;
+ if (isChildEmpty) {
+ assert childRemaining.isEmpty();
+ len--;
+ }
+ byte[] result = new byte[len];
+ int pos = 0;
+ while (dotdots > 0) {
+ result[pos++] = (byte)'.';
+ result[pos++] = (byte)'.';
+ if (isChildEmpty) {
+ if (dotdots > 1) result[pos++] = (byte)'/';
+ } else {
+ result[pos++] = (byte)'/';
}
- byte[] result = new byte[len];
- int pos = 0;
- while (dotdots > 0) {
- result[pos++] = (byte)'.';
- result[pos++] = (byte)'.';
- if (isOtherEmpty) {
- if (dotdots > 1) result[pos++] = (byte)'/';
- } else {
- result[pos++] = (byte)'/';
- }
- dotdots--;
- }
- System.arraycopy(remainder.path, 0, result, pos, remainder.path.length);
- return new UnixPath(getFileSystem(), result);
- } else {
- // no remaining names in other so result is simply a sequence of ".."
- byte[] result = new byte[dotdots*3 - 1];
- int pos = 0;
- while (dotdots > 0) {
- result[pos++] = (byte)'.';
- result[pos++] = (byte)'.';
- // no tailing slash at the end
- if (dotdots > 1)
- result[pos++] = (byte)'/';
- dotdots--;
- }
- return new UnixPath(getFileSystem(), result);
+ dotdots--;
}
+ System.arraycopy(childRemaining.path,0, result, pos,
+ childRemaining.path.length);
+ return new UnixPath(getFileSystem(), result);
}
@Override
- public Path normalize() {
+ public UnixPath normalize() {
final int count = getNameCount();
if (count == 0 || isEmpty())
return this;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java Mon Aug 29 08:53:32 2016 -0700
@@ -375,57 +375,108 @@
return (WindowsPath)path;
}
+ // return true if this path has "." or ".."
+ private boolean hasDotOrDotDot() {
+ int n = getNameCount();
+ for (int i=0; i<n; i++) {
+ String name = elementAsString(i);
+ if (name.length() == 1 && name.charAt(0) == '.')
+ return true;
+ if (name.length() == 2
+ && name.charAt(0) == '.' && name.charAt(1) == '.')
+ return true;
+ }
+ return false;
+ }
+
@Override
public WindowsPath relativize(Path obj) {
- WindowsPath other = toWindowsPath(obj);
- if (this.equals(other))
+ WindowsPath child = toWindowsPath(obj);
+ if (this.equals(child))
return emptyPath();
// can only relativize paths of the same type
- if (this.type != other.type)
+ if (this.type != child.type)
throw new IllegalArgumentException("'other' is different type of Path");
// can only relativize paths if root component matches
- if (!this.root.equalsIgnoreCase(other.root))
+ if (!this.root.equalsIgnoreCase(child.root))
throw new IllegalArgumentException("'other' has different root");
// this path is the empty path
if (this.isEmpty())
- return other;
+ return child;
+
- int bn = this.getNameCount();
- int cn = other.getNameCount();
+ WindowsPath base = this;
+ if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
+ base = base.normalize();
+ child = child.normalize();
+ }
+
+ int baseCount = base.getNameCount();
+ int childCount = child.getNameCount();
// skip matching names
- int n = (bn > cn) ? cn : bn;
+ int n = Math.min(baseCount, childCount);
int i = 0;
while (i < n) {
- if (!this.getName(i).equals(other.getName(i)))
+ if (!base.getName(i).equals(child.getName(i)))
break;
i++;
}
- // append ..\ for remaining names in the base
+ // remaining elements in child
+ WindowsPath childRemaining;
+ boolean isChildEmpty;
+ if (i == childCount) {
+ childRemaining = emptyPath();
+ isChildEmpty = true;
+ } else {
+ childRemaining = child.subpath(i, childCount);
+ isChildEmpty = childRemaining.isEmpty();
+ }
+
+ // matched all of base
+ if (i == baseCount) {
+ return childRemaining;
+ }
+
+ // the remainder of base cannot contain ".."
+ WindowsPath baseRemaining = base.subpath(i, baseCount);
+ if (baseRemaining.hasDotOrDotDot()) {
+ throw new IllegalArgumentException("Unable to compute relative "
+ + " path from " + this + " to " + obj);
+ }
+ if (baseRemaining.isEmpty())
+ return childRemaining;
+
+ // number of ".." needed
+ int dotdots = baseRemaining.getNameCount();
+ if (dotdots == 0) {
+ return childRemaining;
+ }
+
StringBuilder result = new StringBuilder();
- for (int j=i; j<bn; j++) {
+ for (int j=0; j<dotdots; j++) {
result.append("..\\");
}
// append remaining names in child
- if (!other.isEmpty()) {
- for (int j=i; j<cn; j++) {
- result.append(other.getName(j).toString());
+ if (!isChildEmpty) {
+ for (int j=0; j<childRemaining.getNameCount(); j++) {
+ result.append(childRemaining.getName(j).toString());
result.append("\\");
}
}
- // drop trailing slash in result
+ // drop trailing slash
result.setLength(result.length()-1);
return createFromNormalizedPath(getFileSystem(), result.toString());
}
@Override
- public Path normalize() {
+ public WindowsPath normalize() {
final int count = getNameCount();
if (count == 0 || isEmpty())
return this;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java Mon Aug 29 08:53:32 2016 -0700
@@ -390,35 +390,27 @@
for (int i=1; i <= retries; i++) {
String proto = useTCP?"TCP":"UDP";
- try (NetClient kdcClient = NetClient.getInstance(
- proto, kdc, port, timeout)) {
- if (DEBUG) {
- System.out.println(">>> KDCCommunication: kdc=" + kdc
+ if (DEBUG) {
+ System.out.println(">>> KDCCommunication: kdc=" + kdc
+ " " + proto + ":"
+ port + ", timeout="
+ timeout
+ ",Attempt =" + i
+ ", #bytes=" + obuf.length);
+ }
+ try (NetClient kdcClient = NetClient.getInstance(
+ proto, kdc, port, timeout)) {
+ kdcClient.send(obuf);
+ ibuf = kdcClient.receive();
+ break;
+ } catch (SocketTimeoutException se) {
+ if (DEBUG) {
+ System.out.println ("SocketTimeOutException with " +
+ "attempt: " + i);
}
- try {
- /*
- * Send the data to the kdc.
- */
- kdcClient.send(obuf);
- /*
- * And get a response.
- */
- ibuf = kdcClient.receive();
- break;
- } catch (SocketTimeoutException se) {
- if (DEBUG) {
- System.out.println ("SocketTimeOutException with " +
- "attempt: " + i);
- }
- if (i == retries) {
- ibuf = null;
- throw se;
- }
+ if (i == retries) {
+ ibuf = null;
+ throw se;
}
}
}
--- a/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3204,7 +3204,6 @@
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @since 1.4
*/
public void setNull(String parameterName, int sqlType) throws SQLException {
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3240,7 +3239,6 @@
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @since 1.4
*/
public void setNull (String parameterName, int sqlType, String typeName)
throws SQLException{
@@ -3259,7 +3257,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setBoolean(String parameterName, boolean x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3277,7 +3274,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setByte(String parameterName, byte x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3295,7 +3291,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setShort(String parameterName, short x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3313,7 +3308,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setInt(String parameterName, int x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3332,7 +3326,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setLong(String parameterName, long x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3350,7 +3343,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setFloat(String parameterName, float x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3368,7 +3360,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setDouble(String parameterName, double x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3387,7 +3378,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3408,7 +3398,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setString(String parameterName, String x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3428,7 +3417,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setBytes(String parameterName, byte x[]) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -3447,7 +3435,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setTimestamp(String parameterName, java.sql.Timestamp x)
throws SQLException{
@@ -3474,7 +3461,6 @@
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @since 1.4
*/
public void setAsciiStream(String parameterName, java.io.InputStream x, int length)
throws SQLException{
@@ -3500,7 +3486,6 @@
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @since 1.4
*/
public void setBinaryStream(String parameterName, java.io.InputStream x,
int length) throws SQLException{
@@ -3528,7 +3513,6 @@
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @since 1.4
*/
public void setCharacterStream(String parameterName,
java.io.Reader reader,
@@ -3684,7 +3668,6 @@
* this data type
* @see Types
* @see #getParams
- * @since 1.4
*/
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
throws SQLException{
@@ -3710,7 +3693,6 @@
* or <code>STRUCT</code> data type and the JDBC driver does not support
* this data type
* @see #getParams
- * @since 1.4
*/
public void setObject(String parameterName, Object x, int targetSqlType)
throws SQLException{
@@ -3751,7 +3733,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setObject(String parameterName, Object x) throws SQLException{
throw new SQLFeatureNotSupportedException("Feature not supported");
@@ -4024,7 +4005,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setDate(String parameterName, java.sql.Date x)
throws SQLException {
@@ -4050,7 +4030,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
throws SQLException {
@@ -4069,7 +4048,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setTime(String parameterName, java.sql.Time x)
throws SQLException {
@@ -4095,7 +4073,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
throws SQLException {
@@ -4121,7 +4098,6 @@
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #getParams
- * @since 1.4
*/
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
throws SQLException {
@@ -4459,7 +4435,6 @@
* @exception SQLException if a database access error occurs or
* this method is called on a closed <code>PreparedStatement</code>
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method
- * @since 1.4
*/
public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
throw new SQLFeatureNotSupportedException("Feature not supported");
--- a/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/CommonDataSource.java Mon Aug 29 08:53:32 2016 -0700
@@ -57,7 +57,6 @@
* logging is disabled
* @exception java.sql.SQLException if a database access error occurs
* @see #setLogWriter
- * @since 1.4
*/
java.io.PrintWriter getLogWriter() throws SQLException;
@@ -79,7 +78,6 @@
* @param out the new log writer; to disable logging, set to null
* @exception SQLException if a database access error occurs
* @see #getLogWriter
- * @since 1.4
*/
void setLogWriter(java.io.PrintWriter out) throws SQLException;
@@ -94,7 +92,6 @@
* @param seconds the data source login time limit
* @exception SQLException if a database access error occurs.
* @see #getLoginTimeout
- * @since 1.4
*/
void setLoginTimeout(int seconds) throws SQLException;
@@ -109,7 +106,6 @@
* @return the data source login time limit
* @exception SQLException if a database access error occurs.
* @see #setLoginTimeout
- * @since 1.4
*/
int getLoginTimeout() throws SQLException;
--- a/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/ConnectionPoolDataSource.java Mon Aug 29 08:53:32 2016 -0700
@@ -72,6 +72,34 @@
PooledConnection getPooledConnection(String user, String password)
throws SQLException;
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ java.io.PrintWriter getLogWriter() throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLogWriter(java.io.PrintWriter out) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLoginTimeout(int seconds) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ int getLoginTimeout() throws SQLException;
+
//------------------------- JDBC 4.3 -----------------------------------
/**
--- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Mon Aug 29 08:53:32 2016 -0700
@@ -109,6 +109,34 @@
Connection getConnection(String username, String password)
throws SQLException;
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ java.io.PrintWriter getLogWriter() throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLogWriter(java.io.PrintWriter out) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLoginTimeout(int seconds) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ int getLoginTimeout() throws SQLException;
+
// JDBC 4.3
/**
--- a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Mon Aug 29 08:53:32 2016 -0700
@@ -81,7 +81,35 @@
XAConnection getXAConnection(String user, String password)
throws SQLException;
- // JDBC 4.3
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ java.io.PrintWriter getLogWriter() throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLogWriter(java.io.PrintWriter out) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ void setLoginTimeout(int seconds) throws SQLException;
+
+ /**
+ * {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ int getLoginTimeout() throws SQLException;
+
+ // JDBC 4.3
/**
* Creates a new {@code XAConnectionBuilder} instance
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java Mon Aug 29 08:53:32 2016 -0700
@@ -150,7 +150,7 @@
this.macAlgorithm.init(secretKey);
} catch (InvalidKeyException ex) {
// reinstantiate Mac object to work around bug in JDK
- // see: http://bugs.sun.com/view_bug.do?bug_id=4953555
+ // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Mac mac = this.macAlgorithm;
try {
this.macAlgorithm = Mac.getInstance(macAlgorithm.getAlgorithm());
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java Mon Aug 29 08:53:32 2016 -0700
@@ -112,7 +112,7 @@
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK
- // see: http://bugs.sun.com/view_bug.do?bug_id=4953555
+ // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm;
try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java Mon Aug 29 08:53:32 2016 -0700
@@ -139,7 +139,7 @@
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK
- // see: http://bugs.sun.com/view_bug.do?bug_id=4953555
+ // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm;
try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java Mon Aug 29 08:53:32 2016 -0700
@@ -252,7 +252,7 @@
this.signatureAlgorithm.initVerify((PublicKey) publicKey);
} catch (InvalidKeyException ex) {
// reinstantiate Signature object to work around bug in JDK
- // see: http://bugs.sun.com/view_bug.do?bug_id=4953555
+ // see: http://bugs.java.com/view_bug.do?bug_id=4953555
Signature sig = this.signatureAlgorithm;
try {
this.signatureAlgorithm = Signature.getInstance(signatureAlgorithm.getAlgorithm());
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
@@ -38,7 +38,6 @@
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.transforms.Transform;
-import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import javax.xml.crypto.*;
import javax.xml.crypto.dom.DOMCryptoContext;
@@ -150,7 +149,7 @@
if (Utils.secureValidation(xc)) {
String algorithm = getAlgorithm();
- if (Transforms.TRANSFORM_XSLT.equals(algorithm)) {
+ if (Policy.restrictAlg(algorithm)) {
throw new TransformException(
"Transform " + algorithm + " is forbidden when secure validation is enabled"
);
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMManifest.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -110,9 +110,10 @@
localName + ", expected Reference");
}
refs.add(new DOMReference(refElem, context, provider));
- if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
- String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " "
- + "references per Manifest are allowed with secure validation";
+ if (secVal && Policy.restrictNumReferences(refs.size())) {
+ String error = "A maximum of " + Policy.maxReferences()
+ + " references per Manifest are allowed when"
+ + " secure validation is enabled";
throw new MarshalException(error);
}
refElem = DOMUtils.getNextSiblingElement(refElem);
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* ===========================================================================
@@ -51,7 +51,6 @@
import org.w3c.dom.Node;
import org.jcp.xml.dsig.internal.DigesterOutputStream;
-import com.sun.org.apache.xml.internal.security.algorithms.MessageDigestAlgorithm;
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.Base64;
@@ -67,11 +66,6 @@
implements Reference, DOMURIReference {
/**
- * The maximum number of transforms per reference, if secure validation is enabled.
- */
- public static final int MAXIMUM_TRANSFORM_COUNT = 5;
-
- /**
* Look up useC14N11 system property. If true, an explicit C14N11 transform
* will be added if necessary when generating the signature. See section
* 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
@@ -208,9 +202,10 @@
}
transforms.add
(new DOMTransform(transformElem, context, provider));
- if (secVal && (transforms.size() > MAXIMUM_TRANSFORM_COUNT)) {
- String error = "A maxiumum of " + MAXIMUM_TRANSFORM_COUNT + " "
- + "transforms per Reference are allowed with secure validation";
+ if (secVal && Policy.restrictNumTransforms(transforms.size())) {
+ String error = "A maximum of " + Policy.maxTransforms()
+ + " transforms per Reference are allowed when"
+ + " secure validation is enabled";
throw new MarshalException(error);
}
transformElem = DOMUtils.getNextSiblingElement(transformElem);
@@ -227,10 +222,10 @@
Element dmElem = nextSibling;
this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
- if (secVal
- && MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(digestMethodAlgorithm)) {
+ if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
throw new MarshalException(
- "It is forbidden to use algorithm " + digestMethod + " when secure validation is enabled"
+ "It is forbidden to use algorithm " + digestMethodAlgorithm +
+ " when secure validation is enabled"
);
}
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* ===========================================================================
@@ -149,9 +149,10 @@
}
transforms.add
(new DOMTransform(transformElem, context, provider));
- if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) {
- String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " "
- + "transforms per Reference are allowed with secure validation";
+ if (secVal && Policy.restrictNumTransforms(transforms.size())) {
+ String error = "A maximum of " + Policy.maxTransforms()
+ + " transforms per Reference are allowed when"
+ + " secure validation is enabled";
throw new MarshalException(error);
}
transformElem = DOMUtils.getNextSiblingElement(transformElem);
@@ -238,7 +239,8 @@
}
// guard against RetrievalMethod loops
- if ((data instanceof NodeSetData) && Utils.secureValidation(context)) {
+ if ((data instanceof NodeSetData) && Utils.secureValidation(context)
+ && Policy.restrictRetrievalMethodLoops()) {
NodeSetData<?> nsd = (NodeSetData<?>)data;
Iterator<?> i = nsd.iterator();
if (i.hasNext()) {
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMSignedInfo.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -45,7 +45,6 @@
import org.w3c.dom.Node;
import com.sun.org.apache.xml.internal.security.utils.Base64;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
/**
@@ -55,22 +54,9 @@
*/
public final class DOMSignedInfo extends DOMStructure implements SignedInfo {
- /**
- * The maximum number of references per Manifest, if secure validation is enabled.
- */
- public static final int MAXIMUM_REFERENCE_COUNT = 30;
-
private static java.util.logging.Logger log =
java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
- /** Signature - NOT Recommended RSAwithMD5 */
- private static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 =
- Constants.MoreAlgorithmsSpecNS + "rsa-md5";
-
- /** HMAC - NOT Recommended HMAC-MD5 */
- private static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 =
- Constants.MoreAlgorithmsSpecNS + "hmac-md5";
-
private List<Reference> references;
private CanonicalizationMethod canonicalizationMethod;
private SignatureMethod signatureMethod;
@@ -158,10 +144,10 @@
boolean secVal = Utils.secureValidation(context);
String signatureMethodAlgorithm = signatureMethod.getAlgorithm();
- if (secVal && ((ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(signatureMethodAlgorithm)
- || ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(signatureMethodAlgorithm)))) {
+ if (secVal && Policy.restrictAlg(signatureMethodAlgorithm)) {
throw new MarshalException(
- "It is forbidden to use algorithm " + signatureMethod + " when secure validation is enabled"
+ "It is forbidden to use algorithm " + signatureMethodAlgorithm +
+ " when secure validation is enabled"
);
}
@@ -179,9 +165,10 @@
}
refList.add(new DOMReference(refElem, context, provider));
- if (secVal && (refList.size() > MAXIMUM_REFERENCE_COUNT)) {
- String error = "A maxiumum of " + MAXIMUM_REFERENCE_COUNT + " "
- + "references per Manifest are allowed with secure validation";
+ if (secVal && Policy.restrictNumReferences(refList.size())) {
+ String error = "A maximum of " + Policy.maxReferences()
+ + " references per Manifest are allowed when"
+ + " secure validation is enabled";
throw new MarshalException(error);
}
refElem = DOMUtils.getNextSiblingElement(refElem);
--- a/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java Mon Aug 29 08:53:32 2016 -0700
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id: DOMURIDereferencer.java 1231033 2012-01-13 12:12:12Z coheigea $
@@ -73,6 +73,11 @@
boolean secVal = Utils.secureValidation(context);
+ if (secVal && Policy.restrictReferenceUriScheme(uri)) {
+ throw new URIReferenceException(
+ "Uri " + uri + " is forbidden when secure validation is enabled");
+ }
+
// Check if same-document URI and already registered on the context
if (uri != null && uri.length() != 0 && uri.charAt(0) == '#') {
String id = uri.substring(1);
@@ -83,12 +88,19 @@
id = id.substring(i1+1, i2);
}
- Node referencedElem = dcc.getElementById(id);
+ // check if element is registered by Id
+ Node referencedElem = uriAttr.getOwnerDocument().getElementById(id);
+ if (referencedElem == null) {
+ // see if element is registered in DOMCryptoContext
+ referencedElem = dcc.getElementById(id);
+ }
if (referencedElem != null) {
- if (secVal) {
+ if (secVal && Policy.restrictDuplicateIds()) {
Element start = referencedElem.getOwnerDocument().getDocumentElement();
if (!XMLUtils.protectAgainstWrappingAttack(start, (Element)referencedElem, id)) {
- String error = "Multiple Elements with the same ID " + id + " were detected";
+ String error = "Multiple Elements with the same ID "
+ + id + " detected when secure validation"
+ + " is enabled";
throw new URIReferenceException(error);
}
}
@@ -110,9 +122,9 @@
try {
ResourceResolver apacheResolver =
- ResourceResolver.getInstance(uriAttr, baseURI, secVal);
+ ResourceResolver.getInstance(uriAttr, baseURI, false);
XMLSignatureInput in = apacheResolver.resolve(uriAttr,
- baseURI, secVal);
+ baseURI, false);
if (in.isOctetStream()) {
return new ApacheOctetStreamData(in);
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Policy.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.jcp.xml.dsig.internal.dom;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.AccessController;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * The secure validation policy as specified by the
+ * jdk.xml.dsig.secureValidationPolicy security property.
+ */
+public final class Policy {
+
+ // all restrictions are initialized to be unconstrained
+ private static Set<URI> disallowedAlgs = new HashSet<>();
+ private static int maxTrans = Integer.MAX_VALUE;
+ private static int maxRefs = Integer.MAX_VALUE;
+ private static Set<String> disallowedRefUriSchemes = new HashSet<>();
+ private static boolean noDuplicateIds = false;
+ private static boolean noRMLoops = false;
+
+ static {
+ try {
+ initialize();
+ } catch (Exception e) {
+ throw new SecurityException(
+ "Cannot initialize the secure validation policy", e);
+ }
+ }
+
+ private Policy() {}
+
+ private static void initialize() {
+ String prop =
+ AccessController.doPrivileged((PrivilegedAction<String>) () ->
+ Security.getProperty("jdk.xml.dsig.secureValidationPolicy"));
+ if (prop == null || prop.isEmpty()) {
+ // no policy specified, so don't enforce any restrictions
+ return;
+ }
+ String[] entries = prop.split(",");
+ for (String entry : entries) {
+ String[] tokens = entry.split("\\s");
+ String type = tokens[0];
+ switch(type) {
+ case "disallowAlg":
+ if (tokens.length != 2) {
+ error(entry);
+ }
+ disallowedAlgs.add(URI.create(tokens[1]));
+ break;
+ case "maxTransforms":
+ if (tokens.length != 2) {
+ error(entry);
+ }
+ maxTrans = Integer.parseUnsignedInt(tokens[1]);
+ break;
+ case "maxReferences":
+ if (tokens.length != 2) {
+ error(entry);
+ }
+ maxRefs = Integer.parseUnsignedInt(tokens[1]);
+ break;
+ case "disallowReferenceUriSchemes":
+ if (tokens.length == 1) {
+ error(entry);
+ }
+ for (int i = 1; i < tokens.length; i++) {
+ String scheme = tokens[i];
+ disallowedRefUriSchemes.add(
+ scheme.toLowerCase(Locale.ROOT));
+ }
+ break;
+ case "noDuplicateIds":
+ if (tokens.length != 1) {
+ error(entry);
+ }
+ noDuplicateIds = true;
+ break;
+ case "noRetrievalMethodLoops":
+ if (tokens.length != 1) {
+ error(entry);
+ }
+ noRMLoops = true;
+ break;
+ default:
+ error(entry);
+ }
+ }
+ }
+
+ public static boolean restrictAlg(String alg) {
+ try {
+ URI uri = new URI(alg);
+ return disallowedAlgs.contains(uri);
+ } catch (URISyntaxException use) {
+ return false;
+ }
+ }
+
+ public static boolean restrictNumTransforms(int numTrans) {
+ return (numTrans > maxTrans);
+ }
+
+ public static boolean restrictNumReferences(int numRefs) {
+ return (numRefs > maxRefs);
+ }
+
+ public static boolean restrictReferenceUriScheme(String uri) {
+ if (uri != null) {
+ String scheme = java.net.URI.create(uri).getScheme();
+ if (scheme != null) {
+ return disallowedRefUriSchemes.contains(
+ scheme.toLowerCase(Locale.ROOT));
+ }
+ }
+ return false;
+ }
+
+ public static boolean restrictDuplicateIds() {
+ return noDuplicateIds;
+ }
+
+ public static boolean restrictRetrievalMethodLoops() {
+ return noRMLoops;
+ }
+
+ public static Set<URI> disabledAlgs() {
+ return Collections.<URI>unmodifiableSet(disallowedAlgs);
+ }
+
+ public static int maxTransforms() {
+ return maxTrans;
+ }
+
+ public static int maxReferences() {
+ return maxRefs;
+ }
+
+ public static Set<String> disabledReferenceUriSchemes() {
+ return Collections.<String>unmodifiableSet(disallowedRefUriSchemes);
+ }
+
+ private static void error(String entry) {
+ throw new IllegalArgumentException(
+ "Invalid jdk.xml.dsig.secureValidationPolicy entry: " + entry);
+ }
+}
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11RSACipher.java Mon Aug 29 08:53:32 2016 -0700
@@ -358,7 +358,9 @@
System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
if (tmpBuffer.length > outLen) {
- throw new BadPaddingException("Output buffer too small");
+ throw new BadPaddingException(
+ "Output buffer (" + outLen + ") is too small to " +
+ "hold the produced data (" + tmpBuffer.length + ")");
}
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
n = tmpBuffer.length;
--- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_util.c Mon Aug 29 08:53:32 2016 -0700
@@ -558,7 +558,7 @@
pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
if (pCharArray == NULL) { return; }
- *ckpLength = strlen(pCharArray);
+ *ckpLength = (CK_ULONG) strlen(pCharArray);
*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
if (*ckpArray == NULL) {
(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
--- a/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/unix/native/libj2pkcs11/j2secmod_md.c Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
(JNIEnv *env, jclass thisClass, jstring jLibName)
{
+ void *hModule;
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
if (libName == NULL) {
return 0L;
@@ -56,9 +57,9 @@
// look up existing handle only, do not load
#if defined(AIX)
- void *hModule = dlopen(libName, RTLD_LAZY);
+ hModule = dlopen(libName, RTLD_LAZY);
#else
- void *hModule = dlopen(libName, RTLD_NOLOAD);
+ hModule = dlopen(libName, RTLD_NOLOAD);
#endif
dprintf2("-handle for %s: %u\n", libName, hModule);
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
--- a/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c Mon Aug 29 08:53:32 2016 -0700
@@ -31,6 +31,9 @@
#include "j2secmod.h"
+extern void throwNullPointerException(JNIEnv *env, const char *message);
+extern void throwIOException(JNIEnv *env, const char *message);
+
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
HINSTANCE hModule = (HINSTANCE)jHandle;
void *fAddress = GetProcAddress(hModule, functionName);
--- a/jdk/src/jdk.internal.opt/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.internal.opt/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,5 +24,5 @@
*/
module jdk.internal.opt {
- exports jdk.internal.joptsimple to jdk.jlink;
+ exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -78,28 +78,21 @@
private final List<String> args;
private final Set<String> modules;
- public DefaultExecutableImage(Path home, Set<String> modules) {
- this(home, modules, createArgs(home));
- }
-
- private DefaultExecutableImage(Path home, Set<String> modules,
- List<String> args) {
+ DefaultExecutableImage(Path home, Set<String> modules) {
Objects.requireNonNull(home);
- Objects.requireNonNull(args);
if (!Files.exists(home)) {
throw new IllegalArgumentException("Invalid image home");
}
this.home = home;
this.modules = Collections.unmodifiableSet(modules);
- this.args = Collections.unmodifiableList(args);
+ this.args = createArgs(home);
}
private static List<String> createArgs(Path home) {
Objects.requireNonNull(home);
- List<String> javaArgs = new ArrayList<>();
- javaArgs.add(home.resolve("bin").
- resolve(getJavaProcessName()).toString());
- return javaArgs;
+ Path binDir = home.resolve("bin");
+ String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
+ return List.of(binDir.resolve(java).toString());
}
@Override
@@ -130,6 +123,7 @@
private final Path root;
private final Path mdir;
private final Set<String> modules = new HashSet<>();
+ private String targetOsName;
/**
* Default image builder constructor.
@@ -171,6 +165,11 @@
@Override
public void storeFiles(ResourcePool files) {
try {
+ // populate release properties up-front. targetOsName
+ // field is assigned from there and used elsewhere.
+ Properties release = releaseProperties(files);
+ Path bin = root.resolve("bin");
+
files.entries().forEach(f -> {
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
try {
@@ -186,11 +185,11 @@
modules.add(m.name());
}
});
- storeFiles(modules, releaseProperties(files));
+
+ storeFiles(modules, release);
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
// launchers in the bin directory need execute permission
- Path bin = root.resolve("bin");
if (Files.isDirectory(bin)) {
Files.list(bin)
.filter(f -> !f.toString().endsWith(".diz"))
@@ -208,7 +207,11 @@
}
}
- prepareApplicationFiles(files, modules);
+ // If native files are stripped completely, <root>/bin dir won't exist!
+ // So, don't bother generating launcher scripts.
+ if (Files.isDirectory(bin)) {
+ prepareApplicationFiles(files, modules);
+ }
} catch (IOException ex) {
throw new PluginException(ex);
}
@@ -226,6 +229,11 @@
props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
});
+ this.targetOsName = props.getProperty("OS_NAME");
+ if (this.targetOsName == null) {
+ throw new PluginException("TargetPlatform attribute is missing for java.base module");
+ }
+
Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
if (release.isPresent()) {
try (InputStream is = release.get().content()) {
@@ -373,7 +381,7 @@
Files.createLink(dstFile, target);
}
- private static String nativeDir(String filename) {
+ private String nativeDir(String filename) {
if (isWindows()) {
if (filename.endsWith(".dll") || filename.endsWith(".diz")
|| filename.endsWith(".pdb") || filename.endsWith(".map")) {
@@ -386,8 +394,8 @@
}
}
- private static boolean isWindows() {
- return System.getProperty("os.name").startsWith("Windows");
+ private boolean isWindows() {
+ return targetOsName.startsWith("Windows");
}
/**
@@ -452,12 +460,10 @@
}
}
- private static String getJavaProcessName() {
- return isWindows() ? "java.exe" : "java";
- }
-
public static ExecutableImage getExecutableImage(Path root) {
- if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) {
+ Path binDir = root.resolve("bin");
+ if (Files.exists(binDir.resolve("java")) ||
+ Files.exists(binDir.resolve("java.exe"))) {
return new DefaultExecutableImage(root, retrieveModules(root));
}
return null;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java Mon Aug 29 08:53:32 2016 -0700
@@ -172,7 +172,7 @@
private final Plugin lastSorter;
private final List<Plugin> plugins = new ArrayList<>();
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
-
+ private final boolean validate;
public ImagePluginStack() {
this(null, Collections.emptyList(), null);
@@ -181,6 +181,13 @@
public ImagePluginStack(ImageBuilder imageBuilder,
List<Plugin> plugins,
Plugin lastSorter) {
+ this(imageBuilder, plugins, lastSorter, true);
+ }
+
+ public ImagePluginStack(ImageBuilder imageBuilder,
+ List<Plugin> plugins,
+ Plugin lastSorter,
+ boolean validate) {
this.imageBuilder = Objects.requireNonNull(imageBuilder);
this.lastSorter = lastSorter;
this.plugins.addAll(Objects.requireNonNull(plugins));
@@ -190,6 +197,7 @@
resourcePrevisitors.add((ResourcePrevisitor) p);
}
});
+ this.validate = validate;
}
public void operate(ImageProvider provider) throws Exception {
@@ -268,6 +276,7 @@
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
}
}
+
return resPool;
}
@@ -458,7 +467,11 @@
throws Exception {
Objects.requireNonNull(original);
Objects.requireNonNull(transformed);
- imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
+ ResourcePool lastPool = new LastPoolManager(transformed).resourcePool();
+ if (validate) {
+ ResourcePoolConfiguration.validate(lastPool);
+ }
+ imageBuilder.storeFiles(lastPool);
}
public ExecutableImage getExecutableImage() throws IOException {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PathResourcePoolEntry.java Mon Aug 29 08:53:32 2016 -0700
@@ -5,7 +5,7 @@
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classfile" exception as provided
+ * particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jlink.internal;
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
+
+final class ResourcePoolConfiguration {
+ private ResourcePoolConfiguration() {}
+
+ private static ModuleDescriptor descriptorOf(ResourcePoolModule mod) {
+ ModuleDescriptor md = mod.descriptor();
+
+ // drop hashes
+ ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(md.name());
+ md.requires().stream()
+ .forEach(builder::requires);
+ md.exports().stream()
+ .forEach(builder::exports);
+ md.uses().stream()
+ .forEach(builder::uses);
+ md.provides().values().stream()
+ .forEach(builder::provides);
+
+ // build the proper concealed packages
+ Set<String> exps = md.exports().stream()
+ .map(ModuleDescriptor.Exports::source)
+ .collect(Collectors.toSet());
+
+ mod.packages().stream()
+ .filter(pn -> !exps.contains(pn))
+ .forEach(builder::conceals);
+
+ md.version().ifPresent(builder::version);
+ md.mainClass().ifPresent(builder::mainClass);
+ md.osName().ifPresent(builder::osName);
+ md.osArch().ifPresent(builder::osArch);
+ md.osVersion().ifPresent(builder::osVersion);
+
+ return builder.build();
+ }
+
+ private static ModuleReference moduleReference(ModuleDescriptor desc) {
+ return new ModuleReference(desc, null, () -> {
+ IOException ioe = new IOException("<module reader unsupported>");
+ throw new UncheckedIOException(ioe);
+ });
+ }
+
+ private static Map<String, ModuleReference> allModRefs(ResourcePool pool) {
+ return pool.moduleView().modules().
+ collect(Collectors.toMap(ResourcePoolModule::name,
+ m -> moduleReference(descriptorOf(m))));
+ }
+
+ private static void checkPackages(ResourcePool pool) {
+ // check that each resource pool module's packages()
+ // returns a set that is consistent with the module
+ // descriptor of that module.
+
+ pool.moduleView().modules().forEach(m -> {
+ ModuleDescriptor desc = m.descriptor();
+ if (!desc.packages().equals(m.packages())) {
+ throw new RuntimeException("Module " + m.name() +
+ "'s descriptor returns inconsistent package set");
+ }
+ });
+ }
+
+ static Configuration validate(ResourcePool pool) {
+ checkPackages(pool);
+ final Map<String, ModuleReference> nameToModRef = allModRefs(pool);
+ final Set<ModuleReference> allRefs = new HashSet<>(nameToModRef.values());
+
+ final ModuleFinder finder = new ModuleFinder() {
+ @Override
+ public Optional<ModuleReference> find(String name) {
+ return Optional.ofNullable(nameToModRef.get(name));
+ }
+
+ @Override
+ public Set<ModuleReference> findAll() {
+ return allRefs;
+ }
+ };
+
+ return Configuration.empty().resolveRequires(
+ finder, ModuleFinder.of(), nameToModRef.keySet());
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,7 +24,11 @@
*/
package jdk.tools.jlink.internal.plugins;
+import java.io.File;
+import java.io.IOException;
import java.lang.invoke.MethodType;
+import java.nio.file.Files;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
@@ -32,6 +36,7 @@
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
@@ -47,15 +52,9 @@
private static final String NAME = "generate-jli-classes";
- private static final String BMH_PARAM = "bmh";
-
- private static final String BMH_SPECIES_PARAM = "bmh-species";
-
- private static final String DMH_PARAM = "dmh";
-
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
- private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder";
+ private static final String DIRECT_HOLDER = "java/lang/invoke/DirectMethodHandle$Holder";
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
private static final String DMH_INVOKE_STATIC = "invokeStatic";
private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
@@ -63,15 +62,17 @@
private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
- private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder";
-
- private static final String BASIC_FORMS_HANDLE = "java/lang/invoke/LambdaForm$Holder";
+ private static final String DELEGATING_HOLDER = "java/lang/invoke/DelegatingMethodHandle$Holder";
+ private static final String BASIC_FORMS_HOLDER = "java/lang/invoke/LambdaForm$Holder";
+ private static final String INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder";
private static final JavaLangInvokeAccess JLIA
= SharedSecrets.getJavaLangInvokeAccess();
List<String> speciesTypes;
+ List<String> invokerTypes;
+
Map<String, List<String>> dmhMethods;
public GenerateJLIClassesPlugin() {
@@ -117,21 +118,29 @@
}
/**
+ * @return the default invoker forms to generate.
+ */
+ private static List<String> defaultInvokers() {
+ return List.of("LL_L", "LL_I", "LILL_I", "L6_L");
+ }
+
+ /**
* @return the list of default DirectMethodHandle methods to generate.
*/
- public static Map<String, List<String>> defaultDMHMethods() {
+ private static Map<String, List<String>> defaultDMHMethods() {
return Map.of(
- DMH_INVOKE_VIRTUAL, List.of("_L", "L_L", "LI_I", "LL_V"),
- DMH_INVOKE_SPECIAL, List.of("L_I", "L_L", "LF_L", "LD_L", "LL_L",
- "L3_L", "L4_L", "L5_L", "L6_L", "L7_L", "LI_I", "LI_L", "LIL_I",
- "LII_I", "LII_L", "LLI_L", "LLI_I", "LILI_I", "LIIL_L",
- "LIILL_L", "LIILL_I", "LIIL_I", "LILIL_I", "LILILL_I",
- "LILII_I", "LI3_I", "LI3L_I", "LI3LL_I", "LI3_L", "LI4_I"),
- DMH_INVOKE_STATIC, List.of("II_I", "IL_I", "ILIL_I", "ILII_I",
- "_I", "_L", "_V", "D_L", "F_L", "I_I", "II_L", "LI_L",
- "L_V", "L_L", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L",
- "L7_L", "L8_L", "L9_L", "L9I_L", "L9II_L", "L9IIL_L",
- "L10_L", "L11_L", "L12_L", "L13_L", "L13I_L", "L13II_L")
+ DMH_INVOKE_VIRTUAL, List.of("L_L", "LL_L", "LLI_I", "L3_V"),
+ DMH_INVOKE_SPECIAL, List.of("LL_I", "LL_L", "LLF_L", "LLD_L", "L3_L",
+ "L4_L", "L5_L", "L6_L", "L7_L", "L8_L", "LLI_I", "LLI_L",
+ "LLIL_I", "LLII_I", "LLII_L", "L3I_L", "L3I_I", "LLILI_I",
+ "LLIIL_L", "LLIILL_L", "LLIILL_I", "LLIIL_I", "LLILIL_I",
+ "LLILILL_I", "LLILII_I", "LLI3_I", "LLI3L_I", "LLI3LL_I",
+ "LLI3_L", "LLI4_I"),
+ DMH_INVOKE_STATIC, List.of("LII_I", "LIL_I", "LILIL_I", "LILII_I",
+ "L_I", "L_L", "L_V", "LD_L", "LF_L", "LI_I", "LII_L", "LLI_L",
+ "LL_V", "LL_L", "L3_L", "L4_L", "L5_L", "L6_L", "L7_L",
+ "L8_L", "L9_L", "L10_L", "L10I_L", "L10II_L", "L10IIL_L",
+ "L11_L", "L12_L", "L13_L", "L14_L", "L14I_L", "L14II_L")
);
}
@@ -150,72 +159,91 @@
public void configure(Map<String, String> config) {
String mainArgument = config.get(NAME);
- // Enable by default
- boolean bmhEnabled = true;
- boolean dmhEnabled = true;
- if (mainArgument != null) {
- List<String> args = Arrays.asList(mainArgument.split(","));
- if (!args.contains(BMH_PARAM)) {
- bmhEnabled = false;
- }
- if (!args.contains(DMH_PARAM)) {
- dmhEnabled = false;
- }
- }
+ if (mainArgument != null && mainArgument.startsWith("@")) {
+ File file = new File(mainArgument.substring(1));
+ if (file.exists()) {
+ speciesTypes = new ArrayList<>();
+ invokerTypes = new ArrayList<>();
+ dmhMethods = new HashMap<>();
+ Stream<String> lines = fileLines(file);
- if (!bmhEnabled) {
- speciesTypes = List.of();
+ lines.map(line -> line.split(" "))
+ .forEach(parts -> {
+ switch (parts[0]) {
+ case "[BMH_RESOLVE]":
+ speciesTypes.add(expandSignature(parts[1]));
+ break;
+ case "[LF_RESOLVE]":
+ String methodType = parts[3];
+ validateMethodType(methodType);
+ if (parts[1].contains("Invokers")) {
+ invokerTypes.add(methodType);
+ } else if (parts[1].contains("DirectMethodHandle")) {
+ String dmh = parts[2];
+ // ignore getObject etc for now (generated
+ // by default)
+ if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {
+ addDMHMethodType(dmh, methodType);
+ }
+ }
+ break;
+ default: break; // ignore
+ }
+ });
+ }
} else {
- String args = config.get(BMH_SPECIES_PARAM);
- List<String> bmhSpecies;
- if (args != null && !args.isEmpty()) {
- bmhSpecies = Arrays.stream(args.split(","))
- .map(String::trim)
- .filter(s -> !s.isEmpty())
- .collect(Collectors.toList());
- } else {
- bmhSpecies = defaultSpecies();
- }
-
+ List<String> bmhSpecies = defaultSpecies();
// Expand BMH species signatures
speciesTypes = bmhSpecies.stream()
.map(type -> expandSignature(type))
.collect(Collectors.toList());
- }
+
+ invokerTypes = defaultInvokers();
+ validateMethodTypes(invokerTypes);
- // DirectMethodHandles
- if (!dmhEnabled) {
- dmhMethods = Map.of();
- } else {
- dmhMethods = new HashMap<>();
- for (String dmhParam : DMH_METHOD_TYPE_MAP.keySet()) {
- String args = config.get(dmhParam);
- if (args != null && !args.isEmpty()) {
- List<String> dmhMethodTypes = Arrays.stream(args.split(","))
- .map(String::trim)
- .filter(s -> !s.isEmpty())
- .collect(Collectors.toList());
- dmhMethods.put(dmhParam, dmhMethodTypes);
- // Validation check
- for (String type : dmhMethodTypes) {
- String[] typeParts = type.split("_");
- // check return type (second part)
- if (typeParts.length != 2 || typeParts[1].length() != 1
- || "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
- throw new PluginException(
- "Method type signature must be of form [LJIFD]*_[LJIFDV]");
- }
- // expand and check arguments (first part)
- expandSignature(typeParts[0]);
- }
- }
- }
- if (dmhMethods.isEmpty()) {
- dmhMethods = defaultDMHMethods();
+ dmhMethods = defaultDMHMethods();
+ for (List<String> dmhMethodTypes : dmhMethods.values()) {
+ validateMethodTypes(dmhMethodTypes);
}
}
}
+ private void addDMHMethodType(String dmh, String methodType) {
+ validateMethodType(methodType);
+ List<String> methodTypes = dmhMethods.get(dmh);
+ if (methodTypes == null) {
+ methodTypes = new ArrayList<>();
+ dmhMethods.put(dmh, methodTypes);
+ }
+ methodTypes.add(methodType);
+ }
+
+ private Stream<String> fileLines(File file) {
+ try {
+ return Files.lines(file.toPath());
+ } catch (IOException io) {
+ throw new PluginException("Couldn't read file");
+ }
+ }
+
+ private void validateMethodTypes(List<String> dmhMethodTypes) {
+ for (String type : dmhMethodTypes) {
+ validateMethodType(type);
+ }
+ }
+
+ private void validateMethodType(String type) {
+ String[] typeParts = type.split("_");
+ // check return type (second part)
+ if (typeParts.length != 2 || typeParts[1].length() != 1
+ || "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
+ throw new PluginException(
+ "Method type signature must be of form [LJIFD]*_[LJIFDV]");
+ }
+ // expand and check arguments (first part)
+ expandSignature(typeParts[0]);
+ }
+
private static void requireBasicType(char c) {
if ("LIJFD".indexOf(c) < 0) {
throw new PluginException(
@@ -228,9 +256,10 @@
// Copy all but DMH_ENTRY to out
in.transformAndCopy(entry -> {
// filter out placeholder entries
- if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) ||
- entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY) ||
- entry.path().equals(BASIC_FORMS_HANDLE_ENTRY)) {
+ if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) ||
+ entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
+ entry.path().equals(INVOKERS_HOLDER_ENTRY) ||
+ entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) {
return null;
} else {
return entry;
@@ -265,42 +294,72 @@
for (List<String> entry : dmhMethods.values()) {
count += entry.size();
}
- MethodType[] methodTypes = new MethodType[count];
+ MethodType[] directMethodTypes = new MethodType[count];
int[] dmhTypes = new int[count];
int index = 0;
for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
String dmhType = entry.getKey();
for (String type : entry.getValue()) {
- methodTypes[index] = asMethodType(type);
+ // The DMH type to actually ask for is retrieved by removing
+ // the first argument, which needs to be of Object.class
+ MethodType mt = asMethodType(type);
+ if (mt.parameterCount() < 1 ||
+ mt.parameterType(0) != Object.class) {
+ throw new PluginException(
+ "DMH type parameter must start with L");
+ }
+ directMethodTypes[index] = mt.dropParameterTypes(0, 1);
dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType);
index++;
}
}
+ MethodType[] invokerMethodTypes = new MethodType[this.invokerTypes.size()];
+ for (int i = 0; i < invokerTypes.size(); i++) {
+ // The invoker type to ask for is retrieved by removing the first
+ // and the last argument, which needs to be of Object.class
+ MethodType mt = asMethodType(invokerTypes.get(i));
+ final int lastParam = mt.parameterCount() - 1;
+ if (mt.parameterCount() < 2 ||
+ mt.parameterType(0) != Object.class ||
+ mt.parameterType(lastParam) != Object.class) {
+ throw new PluginException(
+ "Invoker type parameter must start and end with L");
+ }
+ mt = mt.dropParameterTypes(lastParam, lastParam + 1);
+ invokerMethodTypes[i] = mt.dropParameterTypes(0, 1);
+ }
try {
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
- DIRECT_METHOD_HANDLE, methodTypes, dmhTypes);
+ DIRECT_HOLDER, directMethodTypes, dmhTypes);
ResourcePoolEntry ndata = ResourcePoolEntry
- .create(DIRECT_METHOD_HANDLE_ENTRY, bytes);
+ .create(DIRECT_METHOD_HOLDER_ENTRY, bytes);
out.add(ndata);
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
- DELEGATING_METHOD_HANDLE, methodTypes);
- ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes);
+ DELEGATING_HOLDER, directMethodTypes);
+ ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes);
out.add(ndata);
- bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HANDLE);
- ndata = ResourcePoolEntry.create(BASIC_FORMS_HANDLE_ENTRY, bytes);
+ bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER,
+ invokerMethodTypes);
+ ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
+ out.add(ndata);
+
+ bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
+ ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);
out.add(ndata);
} catch (Exception ex) {
throw new PluginException(ex);
}
}
- private static final String DIRECT_METHOD_HANDLE_ENTRY =
- "/java.base/" + DIRECT_METHOD_HANDLE + ".class";
- private static final String DELEGATING_METHOD_HANDLE_ENTRY =
- "/java.base/" + DELEGATING_METHOD_HANDLE + ".class";
- private static final String BASIC_FORMS_HANDLE_ENTRY =
- "/java.base/" + BASIC_FORMS_HANDLE + ".class";
+ private static final String DIRECT_METHOD_HOLDER_ENTRY =
+ "/java.base/" + DIRECT_HOLDER + ".class";
+ private static final String DELEGATING_METHOD_HOLDER_ENTRY =
+ "/java.base/" + DELEGATING_HOLDER + ".class";
+ private static final String BASIC_FORMS_HOLDER_ENTRY =
+ "/java.base/" + BASIC_FORMS_HOLDER + ".class";
+ private static final String INVOKERS_HOLDER_ENTRY =
+ "/java.base/" + INVOKERS_HOLDER + ".class";
// Convert LL -> LL, L3 -> LLL
private static String expandSignature(String signature) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Mon Aug 29 08:53:32 2016 -0700
@@ -56,7 +56,7 @@
copy-files.description=\
If files to copy are not absolute path, JDK home dir is used.\n\
-e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewehere/conf.txt
+e.g.: jrt-fs.jar,LICENSE,/home/me/myfile.txt=somewhere/conf.txt
exclude-files.argument=<pattern-list> of files to exclude
@@ -68,10 +68,12 @@
exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
-generate-jli-classes.argument=<bmh[:bmh-species=LL,L3,...]>
+generate-jli-classes.argument=<@filename>
generate-jli-classes.description=\
-Concrete java.lang.invoke classes to generate
+Takes a file hinting to jlink what java.lang.invoke classes to pre-generate. If\n\
+this flag is not specified a default set of classes will be generated, so to \n\
+disable pre-generation supply the name of an empty or non-existing file
installed-modules.description=Fast loading of module descriptors (always enabled)
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java Mon Aug 29 08:53:32 2016 -0700
@@ -165,8 +165,8 @@
walk(inode.child, process);
} else {
process.accept(inode);
- walk(inode.sibling, process);
}
+ walk(inode.sibling, process);
}
/**
--- a/jdk/test/ProblemList.txt Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/ProblemList.txt Mon Aug 29 08:53:32 2016 -0700
@@ -124,10 +124,6 @@
# jdk_lang
java/lang/StringCoding/CheckEncodings.sh 7008363 generic-all
-java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 8160690 generic-all
-java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 8160690 generic-all
-java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 8160690 generic-all
-java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 8160690 generic-all
############################################################################
@@ -211,8 +207,6 @@
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
-sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
-
############################################################################
# jdk_security
--- a/jdk/test/com/sun/jdi/CatchPatternTest.sh Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/com/sun/jdi/CatchPatternTest.sh Mon Aug 29 08:53:32 2016 -0700
@@ -87,7 +87,12 @@
cmd stop in ${classname}.partTwo
runToBkpt
cmd ignore uncaught java.lang.Throwable
- cmd catch all java.lang.I*
+ # Instead of matching java.lang.I* we use two more specific
+ # patterns here. The reason is to avoid matching IncompatibleClassChangeError
+ # (or the subclass NoSuchMethodError) thrown by the
+ # java.lang.invoke infrastructure.
+ cmd catch all java.lang.Il*
+ cmd catch all java.lang.Ind*
cmd cont
cmd cont
cmd cont
--- a/jdk/test/com/sun/jdi/ClassesByName2Test.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/com/sun/jdi/ClassesByName2Test.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,7 @@
*
* @author Tim Bell (based on ClassesByName by Robert Field)
*
- * @modules java.corba
- * jdk.jdi
+ * @modules jdk.jdi
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g ClassesByName2Test.java
* @run driver ClassesByName2Test
@@ -70,10 +69,14 @@
};
Thread two = new Thread ("TWO") {
- public void run () {
- javax.rmi.CORBA.Util.getCodebase(this.getClass());
+ public void run () {
+ try {
+ String s = String.format("%02x", 0xff);
+ } catch (Exception e) {
+ e.printStackTrace();
}
- };
+ }
+ };
two.start();
one.start();
--- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Mon Aug 29 08:53:32 2016 -0700
@@ -205,12 +205,13 @@
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
.replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
- // DMHs may or may not be pre-generated, making frames differ
+ // LFs may or may not be pre-generated, making frames differ
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
- .replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke")
+ .replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
+ .replaceAll("MH\\.invoke", "MH/xxxxxxxx.invoke")
// invoke frames may or may not have basic method type
// information encoded for diagnostic purposes
- .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1")
+ .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z_]+", "xx.invoke$1")
.replaceAll("\\$[0-9]+", "\\$??");
} else {
return produced;
--- a/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,7 +23,6 @@
/*
* @test LFSingleThreadCachingTest
- * @ignore 8129523
* @bug 8046703
* @key randomness
* @summary Test verifies that lambda forms are cached when run with single thread
@@ -33,7 +32,7 @@
* @build LambdaFormTestCase
* @build LFCachingTestCase
* @build LFSingleThreadCachingTest
- * @run main/othervm LFSingleThreadCachingTest
+ * @run main/othervm -XX:ReservedCodeCacheSize=128m LFSingleThreadCachingTest
*/
import java.lang.invoke.MethodHandle;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/HttpCookie/CookieNegativeMaxAge.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005068
+ * @summary Check that any negative maxAge is treated as "unspecified" and
+ * if header contains cookie with "expires" attribute in the past then cookie
+ * is created with maxAge=0 meaning it is specified to be immediately expired.
+ * @run main CookieNegativeMaxAge
+ */
+
+
+import java.net.HttpCookie;
+import java.util.List;
+
+public class CookieNegativeMaxAge {
+
+ public static void main(String... args) {
+ HttpCookie cookie = new HttpCookie("testCookie", "value");
+ cookie.setMaxAge(Integer.MIN_VALUE);
+ if (cookie.hasExpired()) {
+ throw new RuntimeException("Cookie has unexpectedly expired");
+ }
+
+ List<HttpCookie> cookies = HttpCookie.parse("Set-Cookie: " +
+ "expiredCookie=value; expires=Thu, 01 Jan 1970 00:00:00 GMT");
+ if (cookies.size() == 1) {
+ if (cookies.get(0).getMaxAge() != 0) {
+ throw new RuntimeException("Cookie maxAge expected to be 0");
+ }
+ } else {
+ throw new RuntimeException("Header was incorrectly parsed");
+ }
+ }
+}
--- a/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/net/MulticastSocket/NoLoopbackPackets.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
MulticastSocket msock = null;
List<SocketAddress> failedGroups = new ArrayList<SocketAddress>();
+ Sender sender = null;
try {
msock = new MulticastSocket();
int port = msock.getLocalPort();
@@ -80,9 +81,8 @@
groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port));
groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port));
- Thread sender = new Thread(new Sender(groups));
- sender.setDaemon(true); // we want sender to stop when main thread exits
- sender.start();
+ sender = new Sender(groups);
+ new Thread(sender).start();
// Now try to receive multicast packets. we should not see any of them
// since we disable loopback mode.
@@ -107,6 +107,9 @@
}
} finally {
if (msock != null) try { msock.close(); } catch (Exception e) {}
+ if (sender != null) {
+ sender.stop();
+ }
}
if (failedGroups.size() > 0) {
@@ -119,6 +122,7 @@
static class Sender implements Runnable {
private List<SocketAddress> sendToGroups;
+ private volatile boolean stop;
public Sender(List<SocketAddress> groups) {
sendToGroups = groups;
@@ -136,7 +140,7 @@
MulticastSocket msock = new MulticastSocket();
msock.setLoopbackMode(true); // disable loopback mode
- for (;;) {
+ while (!stop) {
for (DatagramPacket packet : packets) {
msock.send(packet);
}
@@ -147,5 +151,9 @@
throw new RuntimeException(e);
}
}
+
+ void stop() {
+ stop = true;
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ */
+
+/*
+ * @test
+ * @bug 8163561
+ * @modules java.base/sun.net.www
+ * @summary Verify that Proxy-Authenticate header is correctly handled
+ *
+ * @run main/othervm ProxyAuthTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.ProxySelector;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpResponse;
+import java.util.Base64;
+
+import sun.net.www.MessageHeader;
+
+public class ProxyAuthTest {
+ private static final String AUTH_USER = "user";
+ private static final String AUTH_PASSWORD = "password";
+
+ public static void main(String[] args) throws Exception {
+ try (ServerSocket ss = new ServerSocket(0)) {
+ int port = ss.getLocalPort();
+ MyProxy proxy = new MyProxy(ss);
+ (new Thread(proxy)).start();
+ System.out.println("Proxy listening port " + port);
+
+ Auth auth = new Auth();
+ InetSocketAddress paddr = new InetSocketAddress("localhost", port);
+
+ URI uri = new URI("http://www.google.ie/");
+ HttpClient client = HttpClient.create()
+ .proxy(ProxySelector.of(paddr))
+ .authenticator(auth)
+ .build();
+ HttpResponse resp = client.request(uri)
+ .GET()
+ .responseAsync()
+ .get();
+ if (resp.statusCode() != 404) {
+ throw new RuntimeException("Unexpected status code: " + resp.statusCode());
+ }
+
+ if (auth.isCalled) {
+ System.out.println("Authenticator is called");
+ } else {
+ throw new RuntimeException("Authenticator is not called");
+ }
+
+ if (!proxy.matched) {
+ throw new RuntimeException("Proxy authentication failed");
+ }
+ }
+ }
+
+ static class Auth extends Authenticator {
+ private volatile boolean isCalled;
+
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ System.out.println("scheme: " + this.getRequestingScheme());
+ isCalled = true;
+ return new PasswordAuthentication(AUTH_USER,
+ AUTH_PASSWORD.toCharArray());
+ }
+ }
+
+ static class MyProxy implements Runnable {
+ final ServerSocket ss;
+ private volatile boolean matched;
+
+ MyProxy(ServerSocket ss) {
+ this.ss = ss;
+ }
+
+ public void run() {
+ for (int i = 0; i < 2; i++) {
+ try (Socket s = ss.accept();
+ InputStream in = s.getInputStream();
+ OutputStream os = s.getOutputStream();
+ BufferedWriter writer = new BufferedWriter(
+ new OutputStreamWriter(os));
+ PrintWriter out = new PrintWriter(writer);) {
+ MessageHeader headers = new MessageHeader(in);
+ System.out.println("Proxy: received " + headers);
+
+ String authInfo = headers
+ .findValue("Proxy-Authorization");
+ if (authInfo != null) {
+ authenticate(authInfo);
+ out.print("HTTP/1.1 404 Not found\r\n");
+ out.print("\r\n");
+ System.out.println("Proxy: 404");
+ out.flush();
+ } else {
+ out.print("HTTP/1.1 407 Proxy Authorization Required\r\n");
+ out.print(
+ "Proxy-Authenticate: Basic realm=\"a fake realm\"\r\n");
+ out.print("\r\n");
+ System.out.println("Proxy: Authorization required");
+ out.flush();
+ }
+ } catch (IOException x) {
+ System.err.println("Unexpected IOException from proxy.");
+ x.printStackTrace();
+ break;
+ }
+ }
+ }
+
+ private void authenticate(String authInfo) throws IOException {
+ try {
+ authInfo.trim();
+ int ind = authInfo.indexOf(' ');
+ String recvdUserPlusPass = authInfo.substring(ind + 1).trim();
+ // extract encoded username:passwd
+ String value = new String(
+ Base64.getMimeDecoder().decode(recvdUserPlusPass));
+ String userPlusPassword = AUTH_USER + ":" + AUTH_PASSWORD;
+ if (userPlusPassword.equals(value)) {
+ matched = true;
+ System.out.println("Proxy: client authentication successful");
+ } else {
+ System.err.println(
+ "Proxy: client authentication failed, expected ["
+ + userPlusPassword + "], actual [" + value
+ + "]");
+ }
+ } catch (Exception e) {
+ throw new IOException(
+ "Proxy received invalid Proxy-Authorization value: "
+ + authInfo);
+ }
+ }
+ }
+
+}
+
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -119,19 +119,31 @@
ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withCachedThreadPool(pool, rand.nextInt(10));
- testShutdownWithChannels(pool, group);
+ try {
+ testShutdownWithChannels(pool, group);
+ } finally {
+ group.shutdown();
+ }
}
for (int i = 0; i < 100; i++) {
int nThreads = 1 + rand.nextInt(8);
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withFixedThreadPool(nThreads, threadFactory);
- testShutdownWithChannels(null, group);
+ try {
+ testShutdownWithChannels(null, group);
+ } finally {
+ group.shutdown();
+ }
}
for (int i = 0; i < 100; i++) {
ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withThreadPool(pool);
- testShutdownWithChannels(pool, group);
+ try {
+ testShutdownWithChannels(pool, group);
+ } finally {
+ group.shutdown();
+ }
}
}
@@ -164,19 +176,31 @@
ExecutorService pool = pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withCachedThreadPool(pool, rand.nextInt(5));
- testShutdownNow(pool, group);
+ try {
+ testShutdownNow(pool, group);
+ } finally {
+ group.shutdown();
+ }
}
for (int i = 0; i < 10; i++) {
int nThreads = 1 + rand.nextInt(8);
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withFixedThreadPool(nThreads, threadFactory);
- testShutdownNow(null, group);
+ try {
+ testShutdownNow(null, group);
+ } finally {
+ group.shutdown();
+ }
}
for (int i = 0; i < 10; i++) {
ExecutorService pool = Executors.newCachedThreadPool();
AsynchronousChannelGroup group = AsynchronousChannelGroup
.withThreadPool(pool);
- testShutdownNow(pool, group);
+ try {
+ testShutdownNow(pool, group);
+ } finally {
+ group.shutdown();
+ }
}
}
@@ -186,78 +210,78 @@
AsynchronousChannelGroup group =
AsynchronousChannelGroup.withFixedThreadPool(1, threadFactory);
- AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
- AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open(group);
+ try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+ AsynchronousServerSocketChannel listener =
+ AsynchronousServerSocketChannel.open(group)) {
- // initiate accept
- listener.bind(new InetSocketAddress(0));
- Future<AsynchronousSocketChannel> result = listener.accept();
-
- // shutdown group
- group.shutdown();
- if (!group.isShutdown())
- throw new RuntimeException("Group should be shutdown");
+ // initiate accept
+ listener.bind(new InetSocketAddress(0));
+ Future<AsynchronousSocketChannel> result = listener.accept();
- // attempt to create another channel
- try {
- AsynchronousSocketChannel.open(group);
- throw new RuntimeException("ShutdownChannelGroupException expected");
- } catch (ShutdownChannelGroupException x) {
- }
- try {
- AsynchronousServerSocketChannel.open(group);
- throw new RuntimeException("ShutdownChannelGroupException expected");
- } catch (ShutdownChannelGroupException x) {
- }
+ // shutdown group
+ group.shutdown();
+ if (!group.isShutdown())
+ throw new RuntimeException("Group should be shutdown");
+
+ // attempt to create another channel
+ try {
+ AsynchronousSocketChannel.open(group);
+ throw new RuntimeException("ShutdownChannelGroupException expected");
+ } catch (ShutdownChannelGroupException x) {
+ }
+ try {
+ AsynchronousServerSocketChannel.open(group);
+ throw new RuntimeException("ShutdownChannelGroupException expected");
+ } catch (ShutdownChannelGroupException x) {
+ }
- // attempt to create another channel by connecting. This should cause
- // the accept operation to fail.
- InetAddress lh = InetAddress.getLocalHost();
- int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
- InetSocketAddress isa = new InetSocketAddress(lh, port);
- ch.connect(isa).get();
- try {
- result.get();
- throw new RuntimeException("Connection was accepted");
- } catch (ExecutionException x) {
- Throwable cause = x.getCause();
- if (!(cause instanceof IOException))
- throw new RuntimeException("Cause should be IOException");
- cause = cause.getCause();
- if (!(cause instanceof ShutdownChannelGroupException))
- throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
- }
+ // attempt to create another channel by connecting. This should cause
+ // the accept operation to fail.
+ InetAddress lh = InetAddress.getLocalHost();
+ int port = ((InetSocketAddress)listener.getLocalAddress()).getPort();
+ InetSocketAddress isa = new InetSocketAddress(lh, port);
+ ch.connect(isa).get();
+ try {
+ result.get();
+ throw new RuntimeException("Connection was accepted");
+ } catch (ExecutionException x) {
+ Throwable cause = x.getCause();
+ if (!(cause instanceof IOException))
+ throw new RuntimeException("Cause should be IOException");
+ cause = cause.getCause();
+ if (!(cause instanceof ShutdownChannelGroupException))
+ throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
+ }
- // initiate another accept even though channel group is shutdown.
- Future<AsynchronousSocketChannel> res = listener.accept();
- try {
- res.get(3, TimeUnit.SECONDS);
- throw new RuntimeException("TimeoutException expected");
- } catch (TimeoutException x) {
+ // initiate another accept even though channel group is shutdown.
+ Future<AsynchronousSocketChannel> res = listener.accept();
+ try {
+ res.get(3, TimeUnit.SECONDS);
+ throw new RuntimeException("TimeoutException expected");
+ } catch (TimeoutException x) {
+ }
+ // connect to the listener which should cause the accept to complete
+ AsynchronousSocketChannel.open().connect(isa);
+ try {
+ res.get();
+ throw new RuntimeException("Connection was accepted");
+ } catch (ExecutionException x) {
+ Throwable cause = x.getCause();
+ if (!(cause instanceof IOException))
+ throw new RuntimeException("Cause should be IOException");
+ cause = cause.getCause();
+ if (!(cause instanceof ShutdownChannelGroupException))
+ throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
+ }
+
+ // group should *not* terminate as channels are open
+ boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
+ if (terminated) {
+ throw new RuntimeException("Group should not have terminated");
+ }
+ } finally {
+ group.shutdown();
}
- // connect to the listener which should cause the accept to complete
- AsynchronousSocketChannel.open().connect(isa);
- try {
- res.get();
- throw new RuntimeException("Connection was accepted");
- } catch (ExecutionException x) {
- Throwable cause = x.getCause();
- if (!(cause instanceof IOException))
- throw new RuntimeException("Cause should be IOException");
- cause = cause.getCause();
- if (!(cause instanceof ShutdownChannelGroupException))
- throw new RuntimeException("IOException cause should be ShutdownChannelGroupException");
- }
-
- // group should *not* terminate as channels are open
- boolean terminated = group.awaitTermination(3, TimeUnit.SECONDS);
- if (terminated)
- throw new RuntimeException("Group should not have terminated");
-
- // close channel; group should terminate quickly
- ch.close();
- listener.close();
- awaitTermination(group);
}
static void miscTests() throws Exception {
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,34 +41,36 @@
public class GroupOfOne {
public static void main(String[] args) throws Exception {
+ final List<AsynchronousSocketChannel> accepted = new ArrayList<>();
+
// create listener to accept connections
- final AsynchronousServerSocketChannel listener =
- AsynchronousServerSocketChannel.open()
- .bind(new InetSocketAddress(0));
- final List<AsynchronousSocketChannel> accepted = new ArrayList<AsynchronousSocketChannel>();
- listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
- public void completed(AsynchronousSocketChannel ch, Void att) {
- synchronized (accepted) {
- accepted.add(ch);
+ try (final AsynchronousServerSocketChannel listener =
+ AsynchronousServerSocketChannel.open()) {
+
+ listener.bind(new InetSocketAddress(0));
+ listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+ public void completed(AsynchronousSocketChannel ch, Void att) {
+ synchronized (accepted) {
+ accepted.add(ch);
+ }
+ listener.accept((Void)null, this);
}
- listener.accept((Void)null, this);
- }
- public void failed(Throwable exc, Void att) {
- }
- });
+ public void failed(Throwable exc, Void att) {
+ }
+ });
- int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
- SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
+ int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+ SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
- test(sa, true, false);
- test(sa, false, true);
- test(sa, true, true);
-
- // clean-up
- listener.close();
- synchronized (accepted) {
- for (AsynchronousSocketChannel ch: accepted) {
- ch.close();
+ test(sa, true, false);
+ test(sa, false, true);
+ test(sa, true, true);
+ } finally {
+ // clean-up
+ synchronized (accepted) {
+ for (AsynchronousSocketChannel ch: accepted) {
+ ch.close();
+ }
}
}
}
@@ -86,60 +88,60 @@
return new Thread(r);
}});
final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+ try {
+ // the latch counts down when:
+ // 1. The read operation fails (expected)
+ // 2. the close/shutdown completes
+ final CountDownLatch latch = new CountDownLatch(2);
- // the latch counts down when:
- // 1. The read operation fails (expected)
- // 2. the close/shutdown completes
- final CountDownLatch latch = new CountDownLatch(2);
+ ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
+ public void completed(Void result, Void att) {
+ System.out.println("Connected");
- ch.connect(sa, (Void)null, new CompletionHandler<Void,Void>() {
- public void completed(Void result, Void att) {
- System.out.println("Connected");
+ // initiate I/O operation that does not complete (successfully)
+ ByteBuffer buf = ByteBuffer.allocate(100);
+ ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
+ public void completed(Integer bytesRead, Void att) {
+ throw new RuntimeException();
+ }
+ public void failed(Throwable exc, Void att) {
+ if (!(exc instanceof AsynchronousCloseException))
+ throw new RuntimeException(exc);
+ System.out.println("Read failed (expected)");
+ latch.countDown();
+ }
+ });
- // initiate I/O operation that does not complete (successfully)
- ByteBuffer buf = ByteBuffer.allocate(100);
- ch.read(buf, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesRead, Void att) {
+ // close channel or shutdown group
+ try {
+ if (closeChannel) {
+ System.out.print("Close channel ...");
+ ch.close();
+ System.out.println(" done.");
+ }
+ if (shutdownGroup) {
+ System.out.print("Shutdown group ...");
+ group.shutdownNow();
+ System.out.println(" done.");
+ }
+ latch.countDown();
+ } catch (IOException e) {
throw new RuntimeException();
}
- public void failed(Throwable exc, Void att) {
- if (!(exc instanceof AsynchronousCloseException))
- throw new RuntimeException(exc);
- System.out.println("Read failed (expected)");
- latch.countDown();
- }
- });
+ }
+ public void failed(Throwable exc, Void att) {
+ throw new RuntimeException(exc);
+ }
+ });
- // close channel or shutdown group
- try {
- if (closeChannel) {
- System.out.print("Close channel ...");
- ch.close();
- System.out.println(" done.");
- }
- if (shutdownGroup) {
- System.out.print("Shutdown group ...");
- group.shutdownNow();
- System.out.println(" done.");
- }
- latch.countDown();
- } catch (IOException e) {
- throw new RuntimeException();
- }
- }
- public void failed(Throwable exc, Void att) {
- throw new RuntimeException(exc);
- }
- });
-
- latch.await();
-
- // clean-up
- group.shutdown();
- boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
- if (!terminated)
- throw new RuntimeException("Group did not terminate");
-
+ latch.await();
+ } finally {
+ // clean-up
+ group.shutdown();
+ boolean terminated = group.awaitTermination(20, TimeUnit.SECONDS);
+ if (!terminated)
+ throw new RuntimeException("Group did not terminate");
+ }
System.out.println("TEST OKAY");
}
}
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Identity.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,89 +76,91 @@
}
public static void main(String[] args) throws Exception {
- // create listener to accept connections
- final AsynchronousServerSocketChannel listener =
- AsynchronousServerSocketChannel.open()
- .bind(new InetSocketAddress(0));
- listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
- public void completed(final AsynchronousSocketChannel ch, Void att) {
- listener.accept((Void)null, this);
- final ByteBuffer buf = ByteBuffer.allocate(100);
- ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
- public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
- if (bytesRead < 0) {
- try { ch.close(); } catch (IOException ignore) { }
- } else {
- buf.clear();
- ch.read(buf, ch, this);
- }
- }
- public void failed(Throwable exc, AsynchronousSocketChannel ch) {
- try { ch.close(); } catch (IOException ignore) { }
- }
- });
- }
- public void failed(Throwable exc, Void att) {
- }
- });
- int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
- SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
-
// create 3-10 channels, each in its own group
final int groupCount = 3 + rand.nextInt(8);
- AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
+ final AsynchronousChannelGroup[] groups = new AsynchronousChannelGroup[groupCount];
final AsynchronousSocketChannel[] channels = new AsynchronousSocketChannel[groupCount];
- for (int i=0; i<groupCount; i++) {
- ThreadFactory factory = createThreadFactory(i);
- AsynchronousChannelGroup group;
- if (rand.nextBoolean()) {
- int nThreads = 1 + rand.nextInt(10);
- group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
- } else {
- ExecutorService pool = Executors.newCachedThreadPool(factory);
- group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
- }
- groups[i] = group;
+
+ // create listener to accept connections
+ try (final AsynchronousServerSocketChannel listener =
+ AsynchronousServerSocketChannel.open()) {
- // create channel in group and connect it to the server
- AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
- ch.connect(sa).get();
- channels[i] = ch;
- }
+ listener.bind(new InetSocketAddress(0));
+ listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+ public void completed(final AsynchronousSocketChannel ch, Void att) {
+ listener.accept((Void)null, this);
+ final ByteBuffer buf = ByteBuffer.allocate(100);
+ ch.read(buf, ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
+ public void completed(Integer bytesRead, AsynchronousSocketChannel ch) {
+ if (bytesRead < 0) {
+ try { ch.close(); } catch (IOException ignore) { }
+ } else {
+ buf.clear();
+ ch.read(buf, ch, this);
+ }
+ }
+ public void failed(Throwable exc, AsynchronousSocketChannel ch) {
+ try { ch.close(); } catch (IOException ignore) { }
+ }
+ });
+ }
+ public void failed(Throwable exc, Void att) {
+ }
+ });
+ int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+ SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port);
- // randomly write to each channel, ensuring that the completion handler
- // is always invoked by a thread with the right identity.
- final AtomicInteger writeCount = new AtomicInteger(100);
- channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
- public void completed(Integer bytesWritten, Integer groupId) {
- if (bytesWritten != 1)
- fail("Expected 1 byte to be written");
- if (!myGroup.get().equals(groupId))
- fail("Handler invoked by thread with the wrong identity");
- if (writeCount.decrementAndGet() > 0) {
- int id = rand.nextInt(groupCount);
- channels[id].write(getBuffer(), id, this);
+ for (int i=0; i<groupCount; i++) {
+ ThreadFactory factory = createThreadFactory(i);
+ AsynchronousChannelGroup group;
+ if (rand.nextBoolean()) {
+ int nThreads = 1 + rand.nextInt(10);
+ group = AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
} else {
- done.countDown();
+ ExecutorService pool = Executors.newCachedThreadPool(factory);
+ group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
}
+ groups[i] = group;
+
+ // create channel in group and connect it to the server
+ AsynchronousSocketChannel ch = AsynchronousSocketChannel.open(group);
+ ch.connect(sa).get();
+ channels[i] = ch;
}
- public void failed(Throwable exc, Integer groupId) {
- fail(exc.getMessage());
- }
- });
-
- // wait until done
- done.await();
- // clean-up
- for (AsynchronousSocketChannel ch: channels)
- ch.close();
- for (AsynchronousChannelGroup group: groups)
- group.shutdownNow();
- listener.close();
+ // randomly write to each channel, ensuring that the completion handler
+ // is always invoked by a thread with the right identity.
+ final AtomicInteger writeCount = new AtomicInteger(100);
+ channels[0].write(getBuffer(), 0, new CompletionHandler<Integer,Integer>() {
+ public void completed(Integer bytesWritten, Integer groupId) {
+ if (bytesWritten != 1)
+ fail("Expected 1 byte to be written");
+ if (!myGroup.get().equals(groupId))
+ fail("Handler invoked by thread with the wrong identity");
+ if (writeCount.decrementAndGet() > 0) {
+ int id = rand.nextInt(groupCount);
+ channels[id].write(getBuffer(), id, this);
+ } else {
+ done.countDown();
+ }
+ }
+ public void failed(Throwable exc, Integer groupId) {
+ fail(exc.getMessage());
+ }
+ });
- if (failed.get())
- throw new RuntimeException("Test failed - see log for details");
+ // wait until done
+ done.await();
+ } finally {
+ // clean-up
+ for (AsynchronousSocketChannel ch: channels)
+ ch.close();
+ for (AsynchronousChannelGroup group: groups)
+ group.shutdownNow();
+
+ if (failed.get())
+ throw new RuntimeException("Test failed - see log for details");
+ }
}
static ByteBuffer getBuffer() {
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Restart.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,21 +66,30 @@
// group with fixed thread pool
int nThreads = 1 + rand.nextInt(4);
AsynchronousChannelGroup group =
- AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
- testRestart(group, 100);
- group.shutdown();
+ AsynchronousChannelGroup.withFixedThreadPool(nThreads, factory);
+ try {
+ testRestart(group, 100);
+ } finally {
+ group.shutdown();
+ }
// group with cached thread pool
ExecutorService pool = Executors.newCachedThreadPool(factory);
group = AsynchronousChannelGroup.withCachedThreadPool(pool, rand.nextInt(5));
- testRestart(group, 100);
- group.shutdown();
+ try {
+ testRestart(group, 100);
+ } finally {
+ group.shutdown();
+ }
// group with custom thread pool
- group = AsynchronousChannelGroup
- .withThreadPool(Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
- testRestart(group, 100);
- group.shutdown();
+ group = AsynchronousChannelGroup.withThreadPool(
+ Executors.newFixedThreadPool(1+rand.nextInt(5), factory));
+ try {
+ testRestart(group, 100);
+ } finally {
+ group.shutdown();
+ }
// give time for threads to terminate
Thread.sleep(3000);
@@ -92,45 +101,43 @@
static void testRestart(AsynchronousChannelGroup group, int count)
throws Exception
{
- AsynchronousServerSocketChannel listener =
- AsynchronousServerSocketChannel.open(group)
- .bind(new InetSocketAddress(0));
+ try (AsynchronousServerSocketChannel listener =
+ AsynchronousServerSocketChannel.open(group)) {
- for (int i=0; i<count; i++) {
- final CountDownLatch latch = new CountDownLatch(1);
+ listener.bind(new InetSocketAddress(0));
+ for (int i=0; i<count; i++) {
+ final CountDownLatch latch = new CountDownLatch(1);
- listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
- public void completed(AsynchronousSocketChannel ch, Void att) {
- try {
- ch.close();
- } catch (IOException ignore) { }
+ listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+ public void completed(AsynchronousSocketChannel ch, Void att) {
+ try {
+ ch.close();
+ } catch (IOException ignore) { }
- latch.countDown();
+ latch.countDown();
- // throw error or runtime exception
- if (rand.nextBoolean()) {
- throw new Error();
- } else {
- throw new RuntimeException();
+ // throw error or runtime exception
+ if (rand.nextBoolean()) {
+ throw new Error();
+ } else {
+ throw new RuntimeException();
+ }
}
- }
- public void failed(Throwable exc, Void att) {
- }
- });
+ public void failed(Throwable exc, Void att) {
+ }
+ });
- // establish loopback connection which should cause completion
- // handler to be invoked.
- int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
- AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
- InetAddress lh = InetAddress.getLocalHost();
- ch.connect(new InetSocketAddress(lh, port)).get();
- ch.close();
+ // establish loopback connection which should cause completion
+ // handler to be invoked.
+ int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort();
+ try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+ InetAddress lh = InetAddress.getLocalHost();
+ ch.connect(new InetSocketAddress(lh, port)).get();
+ }
- // wait for handler to be invoked
- latch.await();
+ // wait for handler to be invoked
+ latch.await();
+ }
}
-
- // clean-up
- listener.close();
}
}
--- a/jdk/test/java/nio/channels/FileChannel/Lock.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/channels/FileChannel/Lock.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
*/
/* @test
- * @bug 4429043 4493595 6332756 6709457
- * @summary The FileChannel file locking
+ * @bug 4429043 4493595 6332756 6709457 7146506
+ * @summary Test FileChannel file locking
*/
import java.io.*;
@@ -33,17 +33,14 @@
/**
* Testing FileChannel's lock method.
*/
-
public class Lock {
public static void main(String[] args) throws Exception {
- if (args.length > 0) {
- if(args[0].equals("1")) {
- MadWriter mw = new MadWriter(args[1], false);
- } else {
- MadWriter mw = new MadWriter(args[1], true);
- }
+ if (args.length == 2) {
+ attemptLock(args[1], args[0].equals("2"));
return;
+ } else if (args.length != 0) {
+ throw new RuntimeException("Wrong number of parameters.");
}
File blah = File.createTempFile("blah", null);
blah.deleteOnExit();
@@ -56,120 +53,128 @@
test2(blah, false);
test3(blah);
test4(blah);
- blah.delete();
- }
-
- private static void test2(File blah, boolean b) throws Exception {
- RandomAccessFile raf = new RandomAccessFile(blah, "rw");
- FileChannel channel = raf.getChannel();
- FileLock lock;
- if (b)
- lock = channel.lock();
- else
- lock = channel.tryLock();
- lock.release();
- channel.close();
}
+ /**
+ * Test mutual locking with other process
+ */
static void test1(File blah, String str) throws Exception {
+ try (RandomAccessFile fis = new RandomAccessFile(blah, "rw")) {
+ FileChannel fc = fis.getChannel();
+ FileLock lock = null;
- // Grab the lock
- RandomAccessFile fis = new RandomAccessFile(blah, "rw");
- FileChannel fc = fis.getChannel();
- FileLock lock = null;
+ // grab the lock
+ if (str.equals("1")) {
+ lock = fc.lock(0, 10, false);
+ if (lock == null)
+ throw new RuntimeException("Lock should not return null");
+ try {
+ fc.lock(5, 10, false);
+ throw new RuntimeException("Overlapping locks allowed");
+ } catch (OverlappingFileLockException e) {} // correct result
+ }
+
+ // execute the tamperer
+ String command = System.getProperty("java.home") +
+ File.separator + "bin" + File.separator + "java";
+ String testClasses = System.getProperty("test.classes");
+ if (testClasses != null)
+ command += " -cp " + testClasses;
+ command += " Lock " + str + " " + blah;
+ Process p = Runtime.getRuntime().exec(command);
- if (str.equals("1")) {
- lock = fc.lock(0, 10, false);
- if (lock == null)
- throw new RuntimeException("Lock should not return null");
- try {
- FileLock lock2 = fc.lock(5, 10, false);
- throw new RuntimeException("Overlapping locks allowed");
- } catch (OverlappingFileLockException e) {
- // Correct result
+ // evaluate System.out of child process
+ String s;
+ boolean hasOutput = false;
+ InputStreamReader isr;
+ isr = new InputStreamReader(p.getInputStream());
+ BufferedReader br = new BufferedReader(isr);
+ while ((s = br.readLine()) != null) {
+ // only throw on Unix as windows over NFS fails...
+ if ((File.separatorChar == '/') && !s.equals("good")) {
+ throw new RuntimeException("Failed: " + s);
+ }
+ hasOutput = true;
+ }
+
+ // evaluate System.err in case of System.out of child process
+ // was empty
+ if (!hasOutput) {
+ isr = new InputStreamReader(p.getErrorStream());
+ br = new BufferedReader(isr);
+ if ((s = br.readLine()) != null) {
+ System.err.println("Error output:");
+ System.err.println(s);
+ while ((s = br.readLine()) != null) {
+ System.err.println(s);
+ }
+ }
+ throw new RuntimeException("Failed, no output");
+ }
+
+ // clean up, check multiple releases
+ if (lock != null) {
+ lock.release();
+ lock.release();
}
}
-
- // Exec the tamperer
- String command = System.getProperty("java.home") +
- File.separator + "bin" + File.separator + "java";
- String testClasses = System.getProperty("test.classes");
- if (testClasses != null)
- command += " -cp " + testClasses;
- command += " Lock " + str + " " + blah;
- Process p = Runtime.getRuntime().exec(command);
-
- BufferedReader in = new BufferedReader
- (new InputStreamReader(p.getInputStream()));
+ }
- String s;
- int count = 0;
- while ((s = in.readLine()) != null) {
- if (!s.equals("good")) {
- if (File.separatorChar == '/') {
- // Fails on windows over NFS...
- throw new RuntimeException("Failed: "+s);
- }
- }
- count++;
- }
-
- if (count == 0) {
- in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
- while ((s = in.readLine()) != null) {
- System.err.println("Error output: " + s);
- }
- throw new RuntimeException("Failed, no output");
- }
-
- // Clean up
- if (lock != null) {
- /* Check multiple releases */
- lock.release();
+ /**
+ * Basic test for FileChannel.lock() and FileChannel.tryLock()
+ */
+ static void test2(File blah, boolean b) throws Exception {
+ try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
+ FileChannel channel = raf.getChannel();
+ FileLock lock;
+ if (b)
+ lock = channel.lock();
+ else
+ lock = channel.tryLock();
lock.release();
}
- fc.close();
- fis.close();
}
- // The overlap check for file locks should be JVM-wide
- private static void test3(File blah) throws Exception {
- FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel();
- FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel();
+ /**
+ * Test that overlapping file locking is not possible when using different
+ * FileChannel objects to the same file path
+ */
+ static void test3(File blah) throws Exception {
+ try (RandomAccessFile raf1 = new RandomAccessFile(blah, "rw");
+ RandomAccessFile raf2 = new RandomAccessFile(blah, "rw"))
+ {
+ FileChannel fc1 = raf1.getChannel();
+ FileChannel fc2 = raf2.getChannel();
- // lock via one channel, and then attempt to lock the same file
- // using a second channel
- FileLock fl1 = fc1.lock();
- try {
- fc2.tryLock();
- throw new RuntimeException("Overlapping locks allowed");
- } catch (OverlappingFileLockException x) {
- }
- try {
+ // lock via one channel, and then attempt to lock the same file
+ // using a second channel
+ FileLock fl1 = fc1.lock();
+ try {
+ fc2.tryLock();
+ throw new RuntimeException("Overlapping locks allowed");
+ } catch (OverlappingFileLockException x) {}
+ try {
+ fc2.lock();
+ throw new RuntimeException("Overlapping locks allowed");
+ } catch (OverlappingFileLockException x) {}
+
+ // release lock and the attempt to lock with the second channel
+ // should succeed.
+ fl1.release();
fc2.lock();
- throw new RuntimeException("Overlapping locks allowed");
- } catch (OverlappingFileLockException x) {
+ try {
+ fc1.lock();
+ throw new RuntimeException("Overlapping locks allowed");
+ } catch (OverlappingFileLockException x) {}
}
-
- // release lock and the attempt to lock with the second channel
- // should succeed.
- fl1.release();
- FileLock fl2 = fc2.lock();
- try {
- fc1.lock();
- throw new RuntimeException("Overlapping locks allowed");
- } catch (OverlappingFileLockException x) {
- }
-
- fc1.close();
- fc2.close();
}
/**
* Test file locking when file is opened for append
*/
static void test4(File blah) throws Exception {
- try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) {
+ try (FileOutputStream fos = new FileOutputStream(blah, true)) {
+ FileChannel fc = fos.getChannel();
fc.tryLock().release();
fc.tryLock(0L, 1L, false).release();
fc.lock().release();
@@ -182,30 +187,31 @@
fc.lock(0L, 1L, false).release();
}
}
-}
-class MadWriter {
- public MadWriter(String s, boolean b) throws Exception {
- File f = new File(s);
- RandomAccessFile fos = new RandomAccessFile(f, "rw");
- FileChannel fc = fos.getChannel();
- if (fc.tryLock(10, 10, false) == null) {
- System.out.println("bad: Failed to grab adjacent lock");
+ /**
+ * Utility method to be run in secondary process which tries to acquire a
+ * lock on a FileChannel
+ */
+ static void attemptLock(String fileName,
+ boolean expectsLock) throws Exception
+ {
+ File f = new File(fileName);
+ try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
+ FileChannel fc = raf.getChannel();
+ if (fc.tryLock(10, 10, false) == null) {
+ System.out.println("bad: Failed to grab adjacent lock");
+ }
+ if (fc.tryLock(0, 10, false) == null) {
+ if (expectsLock)
+ System.out.println("bad");
+ else
+ System.out.println("good");
+ } else {
+ if (expectsLock)
+ System.out.println("good");
+ else
+ System.out.println("bad");
+ }
}
- FileLock lock = fc.tryLock(0, 10, false);
- if (lock == null) {
- if (b)
- System.out.println("bad");
- else
- System.out.println("good");
- } else {
- if (b)
- System.out.println("good");
- else
- System.out.println("bad");
- }
- fc.close();
- fos.close();
}
-
}
--- a/jdk/test/java/nio/file/Files/probeContentType/Basic.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/file/Files/probeContentType/Basic.java Mon Aug 29 08:53:32 2016 -0700
@@ -95,7 +95,7 @@
return 0;
}
- static int checkContentTypes(String[] extensions, String[][] expectedTypes)
+ static int checkContentTypes(String[] extensions, String[] expectedTypes)
throws IOException {
if (extensions.length != expectedTypes.length) {
System.err.println("Parameter array lengths differ");
@@ -112,27 +112,10 @@
System.err.println("Content type of " + extension
+ " cannot be determined");
failures++;
- } else {
- boolean isTypeFound = false;
- for (String s : expectedTypes[i]) {
- if (type.equals(s)) {
- isTypeFound = true;
- break;
- }
- }
- if (!isTypeFound) {
- System.err.printf("Content type: %s; expected: ", type);
- int j = 0;
- for (String s : expectedTypes[i]) {
- if (j++ == 0) {
- System.err.printf("%s", s);
- } else {
- System.err.printf(", or %s", s);
- }
- }
- System.err.println();
- failures++;
- }
+ } else if (!type.equals(expectedTypes[i])) {
+ System.err.printf("Content type: %s; expected: %s%n",
+ type, expectedTypes);
+ failures++;
}
} finally {
Files.delete(file);
@@ -174,8 +157,6 @@
// Verify that certain media extensions are mapped to the correct type.
String[] extensions = new String[]{
- "aac",
- "flac",
"jpg",
"mp3",
"mp4",
@@ -183,15 +164,13 @@
"png",
"webm"
};
- String[][] expectedTypes = new String[][] {
- {"audio/aac", "audio/x-aac", "audio/vnd.dlna.adts"},
- {"audio/flac", "audio/x-flac"},
- {"image/jpeg"},
- {"audio/mpeg"},
- {"video/mp4"},
- {"application/pdf"},
- {"image/png"},
- {"video/webm"}
+ String[] expectedTypes = new String[] {
+ "image/jpeg",
+ "audio/mpeg",
+ "video/mp4",
+ "application/pdf",
+ "image/png",
+ "video/webm"
};
failures += checkContentTypes(extensions, expectedTypes);
--- a/jdk/test/java/nio/file/Path/PathOps.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/file/Path/PathOps.java Mon Aug 29 08:53:32 2016 -0700
@@ -197,6 +197,19 @@
return this;
}
+ PathOps relativizeFail(String other) {
+ out.format("test relativize %s\n", other);
+ checkPath();
+ Path that = FileSystems.getDefault().getPath(other);
+ try {
+ Path result = path.relativize(that);
+ out.format("\tExpected: IllegalArgumentException");
+ out.format("\tActual: %s\n", result);
+ fail();
+ } catch (IllegalArgumentException expected) { }
+ return this;
+ }
+
PathOps normalize(String expected) {
out.println("check normalized path");
checkPath();
@@ -572,29 +585,709 @@
.resolveSibling("C:\\", "C:\\");
// relativize
- test("foo")
- .relativize("foo", "")
- .relativize("bar", "..\\bar")
+ test("C:\\a")
+ .relativize("C:\\a", "")
+ .relativize("C:\\", "..")
+ .relativize("C:\\.", "..")
+ .relativize("C:\\..", "..")
+ .relativize("C:\\..\\..", "..")
+ .relativize("C:\\a\\b", "b")
+ .relativize("C:\\a\\b\\c", "b\\c")
+ .relativize("C:\\a\\.", "") // "." also valid
+ .relativize("C:\\a\\..", "..")
+ .relativize("C:\\x", "..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\a\\b")
+ .relativize("C:\\a\\b", "")
+ .relativize("C:\\a", "..")
+ .relativize("C:\\", "..\\..")
+ .relativize("C:\\.", "..\\..")
+ .relativize("C:\\..", "..\\..")
+ .relativize("C:\\..\\..", "..\\..")
+ .relativize("C:\\a\\b\\c", "c")
+ .relativize("C:\\a\\.", "..")
+ .relativize("C:\\a\\..", "..\\..")
+ .relativize("C:\\x", "..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\a\\b\\c")
+ .relativize("C:\\a\\b\\c", "")
+ .relativize("C:\\a\\b", "..")
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\", "..\\..\\..")
+ .relativize("C:\\.", "..\\..\\..")
+ .relativize("C:\\..", "..\\..\\..")
+ .relativize("C:\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\a\\b\\c\\d", "d")
+ .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("C:\\a\\b\\c\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\c\\..", "..")
+ .relativize("C:\\a\\x", "..\\..\\x")
+ .relativize("C:\\x", "..\\..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\a")
+ .relativize("C:\\a", "")
+ .relativize("C:\\", "..")
+ .relativize("C:\\.", "..")
+ .relativize("C:\\..", "..")
+ .relativize("C:\\..\\..", "..")
+ .relativize("C:\\a\\b", "b")
+ .relativize("C:\\a\\b\\c", "b\\c")
+ .relativize("C:\\a\\.", "") // "." also valid
+ .relativize("C:\\a\\..", "..")
+ .relativize("C:\\x", "..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\a\\b")
+ .relativize("C:\\a\\b", "")
+ .relativize("C:\\a", "..")
+ .relativize("C:\\", "..\\..")
+ .relativize("C:\\.", "..\\..")
+ .relativize("C:\\..", "..\\..")
+ .relativize("C:\\..\\..", "..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..")
+ .relativize("C:\\a\\b\\c", "c")
+ .relativize("C:\\a\\b\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\..", "..")
+ .relativize("C:\\a\\x", "..\\x")
+ .relativize("C:\\x", "..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\..\\a\\b")
+ .relativize("C:\\a\\b", "")
+ .relativize("C:\\a", "..")
+ .relativize("C:\\", "..\\..")
+ .relativize("C:\\.", "..\\..")
+ .relativize("C:\\..", "..\\..")
+ .relativize("C:\\..\\..", "..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..")
+ .relativize("C:\\a\\b\\c", "c")
+ .relativize("C:\\a\\b\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\..", "..")
+ .relativize("C:\\a\\x", "..\\x")
+ .relativize("C:\\x", "..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\a\\b\\c")
+ .relativize("C:\\a\\b\\c", "")
+ .relativize("C:\\a\\b", "..")
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\", "..\\..\\..")
+ .relativize("C:\\.", "..\\..\\..")
+ .relativize("C:\\..", "..\\..\\..")
+ .relativize("C:\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\a\\b\\c\\d", "d")
+ .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("C:\\a\\b\\c\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\c\\..", "..")
+ .relativize("C:\\a\\x", "..\\..\\x")
+ .relativize("C:\\x", "..\\..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\..\\a\\b\\c")
+ .relativize("C:\\a\\b\\c", "")
+ .relativize("C:\\a\\b", "..")
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\", "..\\..\\..")
+ .relativize("C:\\.", "..\\..\\..")
+ .relativize("C:\\..", "..\\..\\..")
+ .relativize("C:\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\a\\b\\c\\d", "d")
+ .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("C:\\a\\b\\c\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\c\\..", "..")
+ .relativize("C:\\a\\x", "..\\..\\x")
+ .relativize("C:\\x", "..\\..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\..\\..\\a\\b\\c")
+ .relativize("C:\\a\\b\\c", "")
+ .relativize("C:\\a\\b", "..")
+ .relativize("C:\\a", "..\\..")
+ .relativize("C:\\", "..\\..\\..")
+ .relativize("C:\\.", "..\\..\\..")
+ .relativize("C:\\..", "..\\..\\..")
+ .relativize("C:\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("C:\\a\\b\\c\\d", "d")
+ .relativize("C:\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("C:\\a\\b\\c\\.", "") // "." also valid
+ .relativize("C:\\a\\b\\c\\..", "..")
+ .relativize("C:\\a\\x", "..\\..\\x")
+ .relativize("C:\\x", "..\\..\\..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\.\\a")
+ .relativize("C:\\a", "")
+ .relativize("C:\\", "..")
+ .relativize("C:\\.", "..")
+ .relativize("C:\\..", "..")
+ .relativize("C:\\..\\..", "..")
+ .relativize("C:\\a\\b", "b")
+ .relativize("C:\\a\\b\\c", "b\\c")
+ .relativize("C:\\a\\.", "") // "." also valid
+ .relativize("C:\\a\\..", "..")
+ .relativize("C:\\x", "..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\..\\a")
+ .relativize("C:\\a", "")
+ .relativize("C:\\", "..")
+ .relativize("C:\\.", "..")
+ .relativize("C:\\..", "..")
+ .relativize("C:\\..\\..", "..")
+ .relativize("C:\\a\\b", "b")
+ .relativize("C:\\a\\b\\c", "b\\c")
+ .relativize("C:\\a\\.", "") // "." also valid
+ .relativize("C:\\a\\..", "..")
+ .relativize("C:\\x", "..\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:\\a\\..")
+ .relativize("C:\\a", "a")
+ .relativize("C:\\", "") // "." is also valid
+ .relativize("C:\\.", "")
+ .relativize("C:\\..", "")
+ .relativize("C:\\..\\..", "")
+ .relativize("C:\\a\\.", "a")
+ .relativize("C:\\a\\..", "")
+ .relativize("C:\\x", "x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("C:a")
+ .relativize("C:a", "")
+ .relativize("C:", "..")
+ .relativize("C:.", "..")
+ .relativize("C:..", "..\\..")
+ .relativize("C:..\\..", "..\\..\\..")
+ .relativize("C:.\\..", "..\\..")
+ .relativize("C:a\\b", "b")
+ .relativize("C:a\\b\\c", "b\\c")
+ .relativize("C:..\\x", "..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("C:a\\b")
+ .relativize("C:a\\b", "")
+ .relativize("C:a", "..")
+ .relativize("C:", "..\\..")
+ .relativize("C:.", "..\\..")
+ .relativize("C:..", "..\\..\\..")
+ .relativize("C:..\\..", "..\\..\\..\\..")
+ .relativize("C:.\\..", "..\\..\\..")
+ .relativize("C:a\\b\\c", "c")
+ .relativize("C:..\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("C:a\\b\\c")
+ .relativize("C:a\\b\\c", "")
+ .relativize("C:a\\b", "..")
+ .relativize("C:a", "..\\..")
+ .relativize("C:", "..\\..\\..")
+ .relativize("C:.", "..\\..\\..")
+ .relativize("C:..", "..\\..\\..\\..")
+ .relativize("C:..\\..", "..\\..\\..\\..\\..")
+ .relativize("C:.\\..", "..\\..\\..\\..")
+ .relativize("C:a\\b\\c\\d", "d")
+ .relativize("C:a\\b\\c\\d\\e", "d\\e")
+ .relativize("C:a\\x", "..\\..\\x")
+ .relativize("C:..\\x", "..\\..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("C:")
+ .relativize("C:a", "a")
+ .relativize("C:a\\b\\c", "a\\b\\c")
+ .relativize("C:", "")
+ .relativize("C:.", "") // "" also valid
+ .relativize("C:..", "..")
+ .relativize("C:..\\..", "..\\..")
+ .relativize("C:.\\..", "..")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("C:..")
+ .relativize("C:..\\a", "a")
+ .relativize("C:..", "")
+ .relativize("C:.\\..", "")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("C:..\\a")
+ .relativize("C:..\\a\\b", "b")
+ .relativize("C:..\\a", "")
+ .relativize("C:..", "..")
+ .relativize("C:.\\..", "..")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("C:..\\a\\b")
+ .relativize("C:..\\a\\b\\c", "c")
+ .relativize("C:..\\a\\b", "")
+ .relativize("C:..\\a", "..")
+ .relativize("C:..", "..\\..")
+ .relativize("C:.\\..", "..\\..")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail("x");
+ test("C:a\\..")
+ .relativize("C:b", "b")
+ .relativize("C:", "")
+ .relativize("C:.", "") // "." also valid
+ .relativize("C:..", "..")
+ .relativize("C:a\\..\\b", "b")
+ .relativize("C:a\\..", "")
+ .relativize("C:..\\b", "..\\b")
+ .relativize("C:b\\..", "")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("x");
+ test("C:a\\..\\b")
+ .relativize("C:a\\..\\b", "")
+ .relativize("C:a\\..", "..")
+ .relativize("C:", "..")
+ .relativize("C:.", "..")
+ .relativize("C:..", "..\\..")
+ .relativize("C:b", "")
+ .relativize("C:c", "..\\c")
+ .relativize("C:..\\c", "..\\..\\c")
+ .relativize("C:a\\..\\b\\c", "c")
+ .relativizeFail("C:\\x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("x");
+ test("\\a")
+ .relativize("\\a", "")
+ .relativize("\\", "..")
+ .relativize("\\.", "..")
+ .relativize("\\..", "..")
+ .relativize("\\..\\..", "..")
+ .relativize("\\a\\b", "b")
+ .relativize("\\a\\b\\c", "b\\c")
+ .relativize("\\a\\.", "") // "." also valid
+ .relativize("\\a\\..", "..")
+ .relativize("\\x", "..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\a\\b")
+ .relativize("\\a\\b", "")
+ .relativize("\\a", "..")
+ .relativize("\\", "..\\..")
+ .relativize("\\.", "..\\..")
+ .relativize("\\..", "..\\..")
+ .relativize("\\..\\..", "..\\..")
+ .relativize("\\a\\b\\c", "c")
+ .relativize("\\a\\.", "..")
+ .relativize("\\a\\..", "..\\..")
+ .relativize("\\x", "..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\a\\b\\c")
+ .relativize("\\a\\b\\c", "")
+ .relativize("\\a\\b", "..")
+ .relativize("\\a", "..\\..")
+ .relativize("\\", "..\\..\\..")
+ .relativize("\\.", "..\\..\\..")
+ .relativize("\\..", "..\\..\\..")
+ .relativize("\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("\\a\\b\\c\\d", "d")
+ .relativize("\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("\\a\\b\\c\\.", "") // "." also valid
+ .relativize("\\a\\b\\c\\..", "..")
+ .relativize("\\a\\x", "..\\..\\x")
+ .relativize("\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\a")
+ .relativize("\\a", "")
+ .relativize("\\", "..")
+ .relativize("\\.", "..")
+ .relativize("\\..", "..")
+ .relativize("\\..\\..", "..")
+ .relativize("\\a\\b", "b")
+ .relativize("\\a\\b\\c", "b\\c")
+ .relativize("\\a\\.", "") // "." also valid
+ .relativize("\\a\\..", "..")
+ .relativize("\\x", "..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\a\\b")
+ .relativize("\\a\\b", "")
+ .relativize("\\a", "..")
+ .relativize("\\", "..\\..")
+ .relativize("\\.", "..\\..")
+ .relativize("\\..", "..\\..")
+ .relativize("\\..\\..", "..\\..")
+ .relativize("\\..\\..\\..", "..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..")
+ .relativize("\\a\\b\\c", "c")
+ .relativize("\\a\\b\\.", "") // "." also valid
+ .relativize("\\a\\b\\..", "..")
+ .relativize("\\a\\x", "..\\x")
+ .relativize("\\x", "..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\..\\a\\b")
+ .relativize("\\a\\b", "")
+ .relativize("\\a", "..")
+ .relativize("\\", "..\\..")
+ .relativize("\\.", "..\\..")
+ .relativize("\\..", "..\\..")
+ .relativize("\\..\\..", "..\\..")
+ .relativize("\\..\\..\\..", "..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..")
+ .relativize("\\a\\b\\c", "c")
+ .relativize("\\a\\b\\.", "") // "." also valid
+ .relativize("\\a\\b\\..", "..")
+ .relativize("\\a\\x", "..\\x")
+ .relativize("\\x", "..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\a\\b\\c")
+ .relativize("\\a\\b\\c", "")
+ .relativize("\\a\\b", "..")
+ .relativize("\\a", "..\\..")
+ .relativize("\\", "..\\..\\..")
+ .relativize("\\.", "..\\..\\..")
+ .relativize("\\..", "..\\..\\..")
+ .relativize("\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("\\a\\b\\c\\d", "d")
+ .relativize("\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("\\a\\b\\c\\.", "") // "." also valid
+ .relativize("\\a\\b\\c\\..", "..")
+ .relativize("\\a\\x", "..\\..\\x")
+ .relativize("\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\..\\a\\b\\c")
+ .relativize("\\a\\b\\c", "")
+ .relativize("\\a\\b", "..")
+ .relativize("\\a", "..\\..")
+ .relativize("\\", "..\\..\\..")
+ .relativize("\\.", "..\\..\\..")
+ .relativize("\\..", "..\\..\\..")
+ .relativize("\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("\\a\\b\\c\\d", "d")
+ .relativize("\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("\\a\\b\\c\\.", "") // "." also valid
+ .relativize("\\a\\b\\c\\..", "..")
+ .relativize("\\a\\x", "..\\..\\x")
+ .relativize("\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\..\\..\\a\\b\\c")
+ .relativize("\\a\\b\\c", "")
+ .relativize("\\a\\b", "..")
+ .relativize("\\a", "..\\..")
+ .relativize("\\", "..\\..\\..")
+ .relativize("\\.", "..\\..\\..")
+ .relativize("\\..", "..\\..\\..")
+ .relativize("\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..", "..\\..\\..")
+ .relativize("\\..\\..\\..\\..", "..\\..\\..")
+ .relativize("\\a\\b\\c\\d", "d")
+ .relativize("\\a\\b\\c\\d\\e", "d\\e")
+ .relativize("\\a\\b\\c\\.", "") // "." also valid
+ .relativize("\\a\\b\\c\\..", "..")
+ .relativize("\\a\\x", "..\\..\\x")
+ .relativize("\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\.\\a")
+ .relativize("\\a", "")
+ .relativize("\\", "..")
+ .relativize("\\.", "..")
+ .relativize("\\..", "..")
+ .relativize("\\..\\..", "..")
+ .relativize("\\a\\b", "b")
+ .relativize("\\a\\b\\c", "b\\c")
+ .relativize("\\a\\.", "") // "." also valid
+ .relativize("\\a\\..", "..")
+ .relativize("\\x", "..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\..\\a")
+ .relativize("\\a", "")
+ .relativize("\\", "..")
+ .relativize("\\.", "..")
+ .relativize("\\..", "..")
+ .relativize("\\..\\..", "..")
+ .relativize("\\a\\b", "b")
+ .relativize("\\a\\b\\c", "b\\c")
+ .relativize("\\a\\.", "") // "." also valid
+ .relativize("\\a\\..", "..")
+ .relativize("\\x", "..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\a\\..")
+ .relativize("\\a", "a")
+ .relativize("\\", "") // "." is also valid
+ .relativize("\\.", "")
+ .relativize("\\..", "")
+ .relativize("\\..\\..", "")
+ .relativize("\\a\\.", "a")
+ .relativize("\\a\\..", "")
+ .relativize("\\x", "x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("\\")
+ .relativize("\\a", "a")
+ .relativize("\\", "") // "." is also valid
+ .relativize("\\.", "")
+ .relativize("\\..", "")
+ .relativize("\\..\\..", "")
+ .relativize("\\a\\.", "a")
+ .relativize("\\a\\..", "")
+ .relativize("\\x", "x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("a")
+ .relativize("a", "")
+ .relativize("", "..")
+ .relativize(".", "..")
.relativize("..", "..\\..")
- .relativize("", "..");
- test("foo\\bar")
- .relativize("foo\\bar", "")
- .relativize("foo", "..")
- .relativize("gus", "..\\..\\gus")
+ .relativize("..\\..", "..\\..\\..")
+ .relativize(".\\..", "..\\..")
+ .relativize("a\\b", "b")
+ .relativize("a\\b\\c", "b\\c")
+ .relativize("..\\x", "..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("a\\b")
+ .relativize("a\\b", "")
+ .relativize("a", "..")
+ .relativize("", "..\\..")
+ .relativize(".", "..\\..")
.relativize("..", "..\\..\\..")
- .relativize("", "..\\..");
- test("C:\\a\\b\\c")
- .relativize("C:\\a", "..\\..")
- .relativize("C:\\a\\b\\c", "")
- .relativize("C:\\x", "..\\..\\..\\x");
- test("\\\\server\\share\\foo")
- .relativize("\\\\server\\share\\bar", "..\\bar")
- .relativize("\\\\server\\share\\foo", "");
+ .relativize("..\\..", "..\\..\\..\\..")
+ .relativize(".\\..", "..\\..\\..")
+ .relativize("a\\b\\c", "c")
+ .relativize("..\\x", "..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("a\\b\\c")
+ .relativize("a\\b\\c", "")
+ .relativize("a\\b", "..")
+ .relativize("a", "..\\..")
+ .relativize("", "..\\..\\..")
+ .relativize(".", "..\\..\\..")
+ .relativize("..", "..\\..\\..\\..")
+ .relativize("..\\..", "..\\..\\..\\..\\..")
+ .relativize(".\\..", "..\\..\\..\\..")
+ .relativize("a\\b\\c\\d", "d")
+ .relativize("a\\b\\c\\d\\e", "d\\e")
+ .relativize("a\\x", "..\\..\\x")
+ .relativize("..\\x", "..\\..\\..\\..\\x")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
test("")
.relativize("a", "a")
.relativize("a\\b\\c", "a\\b\\c")
+ .relativize("", "")
+ .relativize(".", ".")
.relativize("..", "..")
- .relativize("", "");
+ .relativize("..\\..", "..\\..")
+ .relativize(".\\..", ".\\..") // ".." also valid
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("..")
+ .relativize("..\\a", "a")
+ .relativize("..", "")
+ .relativize(".\\..", "")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("..\\a")
+ .relativize("..\\a\\b", "b")
+ .relativize("..\\a", "")
+ .relativize("..", "..")
+ .relativize(".\\..", "..")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("..\\a\\b")
+ .relativize("..\\a\\b\\c", "c")
+ .relativize("..\\a\\b", "")
+ .relativize("..\\a", "..")
+ .relativize("..", "..\\..")
+ .relativize(".\\..", "..\\..")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x")
+ .relativizeFail("")
+ .relativizeFail("x");
+ test("a\\..")
+ .relativize("b", "b")
+ .relativize("", "")
+ .relativize(".", "") // "." also valid
+ .relativize("..", "..")
+ .relativize("a\\..\\b", "b")
+ .relativize("a\\..", "")
+ .relativize("..\\b", "..\\b")
+ .relativize("b\\..", "")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
+ test("a\\..\\b")
+ .relativize("a\\..\\b", "")
+ .relativize("a\\..", "..")
+ .relativize("", "..")
+ .relativize(".", "..")
+ .relativize("..", "..\\..")
+ .relativize("b", "")
+ .relativize("c", "..\\c")
+ .relativize("..\\c", "..\\..\\c")
+ .relativize("a\\..\\b\\c", "c")
+ .relativizeFail("C:\\x")
+ .relativizeFail("C:x")
+ .relativizeFail("\\")
+ .relativizeFail("\\x");
// normalize
test("C:\\")
@@ -971,20 +1664,324 @@
.resolve("", "");
// relativize
+ test("/a")
+ .relativize("/a", "")
+ .relativize("/", "..")
+ .relativize("/.", "..")
+ .relativize("/..", "..")
+ .relativize("/../..", "..")
+ .relativize("/a/b", "b")
+ .relativize("/a/b/c", "b/c")
+ .relativize("/a/.", "") // "." also valid
+ .relativize("/a/..", "..")
+ .relativize("/x", "../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/a/b")
+ .relativize("/a/b", "")
+ .relativize("/a", "..")
+ .relativize("/", "../..")
+ .relativize("/.", "../..")
+ .relativize("/..", "../..")
+ .relativize("/../..", "../..")
+ .relativize("/a/b/c", "c")
+ .relativize("/a/.", "..")
+ .relativize("/a/..", "../..")
+ .relativize("/x", "../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
test("/a/b/c")
.relativize("/a/b/c", "")
+ .relativize("/a/b", "..")
+ .relativize("/a", "../..")
+ .relativize("/", "../../..")
+ .relativize("/.", "../../..")
+ .relativize("/..", "../../..")
+ .relativize("/../..", "../../..")
+ .relativize("/../../..", "../../..")
+ .relativize("/../../../..", "../../..")
+ .relativize("/a/b/c/d", "d")
.relativize("/a/b/c/d/e", "d/e")
+ .relativize("/a/b/c/.", "") // "." also valid
+ .relativize("/a/b/c/..", "..")
+ .relativize("/a/x", "../../x")
+ .relativize("/x", "../../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../a")
+ .relativize("/a", "")
+ .relativize("/", "..")
+ .relativize("/.", "..")
+ .relativize("/..", "..")
+ .relativize("/../..", "..")
+ .relativize("/a/b", "b")
+ .relativize("/a/b/c", "b/c")
+ .relativize("/a/.", "") // "." also valid
+ .relativize("/a/..", "..")
+ .relativize("/x", "../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../a/b")
+ .relativize("/a/b", "")
+ .relativize("/a", "..")
+ .relativize("/", "../..")
+ .relativize("/.", "../..")
+ .relativize("/..", "../..")
+ .relativize("/../..", "../..")
+ .relativize("/../../..", "../..")
+ .relativize("/../../../..", "../..")
+ .relativize("/a/b/c", "c")
+ .relativize("/a/b/.", "") // "." also valid
+ .relativize("/a/b/..", "..")
+ .relativize("/a/x", "../x")
+ .relativize("/x", "../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../../a/b")
+ .relativize("/a/b", "")
+ .relativize("/a", "..")
+ .relativize("/", "../..")
+ .relativize("/.", "../..")
+ .relativize("/..", "../..")
+ .relativize("/../..", "../..")
+ .relativize("/../../..", "../..")
+ .relativize("/../../../..", "../..")
+ .relativize("/a/b/c", "c")
+ .relativize("/a/b/.", "") // "." also valid
+ .relativize("/a/b/..", "..")
+ .relativize("/a/x", "../x")
+ .relativize("/x", "../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../a/b/c")
+ .relativize("/a/b/c", "")
+ .relativize("/a/b", "..")
+ .relativize("/a", "../..")
+ .relativize("/", "../../..")
+ .relativize("/.", "../../..")
+ .relativize("/..", "../../..")
+ .relativize("/../..", "../../..")
+ .relativize("/../../..", "../../..")
+ .relativize("/../../../..", "../../..")
+ .relativize("/a/b/c/d", "d")
+ .relativize("/a/b/c/d/e", "d/e")
+ .relativize("/a/b/c/.", "") // "." also valid
+ .relativize("/a/b/c/..", "..")
+ .relativize("/a/x", "../../x")
+ .relativize("/x", "../../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../../a/b/c")
+ .relativize("/a/b/c", "")
+ .relativize("/a/b", "..")
+ .relativize("/a", "../..")
+ .relativize("/", "../../..")
+ .relativize("/.", "../../..")
+ .relativize("/..", "../../..")
+ .relativize("/../..", "../../..")
+ .relativize("/../../..", "../../..")
+ .relativize("/../../../..", "../../..")
+ .relativize("/a/b/c/d", "d")
+ .relativize("/a/b/c/d/e", "d/e")
+ .relativize("/a/b/c/.", "") // "." also valid
+ .relativize("/a/b/c/..", "..")
.relativize("/a/x", "../../x")
- .relativize("/x", "../../../x");
+ .relativize("/x", "../../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../../../a/b/c")
+ .relativize("/a/b/c", "")
+ .relativize("/a/b", "..")
+ .relativize("/a", "../..")
+ .relativize("/", "../../..")
+ .relativize("/.", "../../..")
+ .relativize("/..", "../../..")
+ .relativize("/../..", "../../..")
+ .relativize("/../../..", "../../..")
+ .relativize("/../../../..", "../../..")
+ .relativize("/a/b/c/d", "d")
+ .relativize("/a/b/c/d/e", "d/e")
+ .relativize("/a/b/c/.", "") // "." also valid
+ .relativize("/a/b/c/..", "..")
+ .relativize("/a/x", "../../x")
+ .relativize("/x", "../../../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/./a")
+ .relativize("/a", "")
+ .relativize("/", "..")
+ .relativize("/.", "..")
+ .relativize("/..", "..")
+ .relativize("/../..", "..")
+ .relativize("/a/b", "b")
+ .relativize("/a/b/c", "b/c")
+ .relativize("/a/.", "") // "." also valid
+ .relativize("/a/..", "..")
+ .relativize("/x", "../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/../a")
+ .relativize("/a", "")
+ .relativize("/", "..")
+ .relativize("/.", "..")
+ .relativize("/..", "..")
+ .relativize("/../..", "..")
+ .relativize("/a/b", "b")
+ .relativize("/a/b/c", "b/c")
+ .relativize("/a/.", "") // "." also valid
+ .relativize("/a/..", "..")
+ .relativize("/x", "../x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/a/..")
+ .relativize("/a", "a")
+ .relativize("/", "") // "." is also valid
+ .relativize("/.", "")
+ .relativize("/..", "")
+ .relativize("/../..", "")
+ .relativize("/a/.", "a")
+ .relativize("/a/..", "")
+ .relativize("/x", "x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("/")
+ .relativize("/a", "a")
+ .relativize("/", "") // "." is also valid
+ .relativize("/.", "")
+ .relativize("/..", "")
+ .relativize("/../..", "")
+ .relativize("/a/.", "a")
+ .relativize("/a/..", "")
+ .relativize("/x", "x")
+ .relativizeFail("x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("..");
+ test("a")
+ .relativize("a", "")
+ .relativize("", "..")
+ .relativize(".", "..")
+ .relativize("..", "../..")
+ .relativize("../..", "../../..")
+ .relativize("./..", "../..")
+ .relativize("a/b", "b")
+ .relativize("a/b/c", "b/c")
+ .relativize("../x", "../../x")
+ .relativizeFail("/")
+ .relativizeFail("/x");
+ test("a/b")
+ .relativize("a/b", "")
+ .relativize("a", "..")
+ .relativize("", "../..")
+ .relativize(".", "../..")
+ .relativize("..", "../../..")
+ .relativize("../..", "../../../..")
+ .relativize("./..", "../../..")
+ .relativize("a/b/c", "c")
+ .relativize("../x", "../../../x")
+ .relativizeFail("/")
+ .relativizeFail("/x");
test("a/b/c")
+ .relativize("a/b/c", "")
+ .relativize("a/b", "..")
+ .relativize("a", "../..")
+ .relativize("", "../../..")
+ .relativize(".", "../../..")
+ .relativize("..", "../../../..")
+ .relativize("../..", "../../../../..")
+ .relativize("./..", "../../../..")
.relativize("a/b/c/d", "d")
+ .relativize("a/b/c/d/e", "d/e")
.relativize("a/x", "../../x")
- .relativize("x", "../../../x")
- .relativize("", "../../..");
+ .relativize("../x", "../../../../x")
+ .relativizeFail("/")
+ .relativizeFail("/x");
test("")
.relativize("a", "a")
.relativize("a/b/c", "a/b/c")
- .relativize("", "");
+ .relativize("", "")
+ .relativize(".", ".")
+ .relativize("..", "..")
+ .relativize("../..", "../..")
+ .relativize("./..", "./..") // ".." also valid
+ .relativizeFail("/")
+ .relativizeFail("/x");
+ test("..")
+ .relativize("../a", "a")
+ .relativize("..", "")
+ .relativize("./..", "")
+ .relativizeFail("/")
+ .relativizeFail("/x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("../a")
+ .relativize("../a/b", "b")
+ .relativize("../a", "")
+ .relativize("..", "..")
+ .relativize("./..", "..")
+ .relativizeFail("/")
+ .relativizeFail("/x")
+ .relativizeFail("")
+ .relativizeFail(".")
+ .relativizeFail("x");
+ test("../a/b")
+ .relativize("../a/b/c", "c")
+ .relativize("../a/b", "")
+ .relativize("../a", "..")
+ .relativize("..", "../..")
+ .relativize("./..", "../..")
+ .relativizeFail("/")
+ .relativizeFail("/x")
+ .relativizeFail("")
+ .relativizeFail("x");
+ test("a/..")
+ .relativize("b", "b")
+ .relativize("", "")
+ .relativize(".", "") // "." also valid
+ .relativize("..", "..")
+ .relativize("a/../b", "b")
+ .relativize("a/..", "")
+ .relativize("../b", "../b")
+ .relativize("b/..", "")
+ .relativizeFail("/")
+ .relativizeFail("/x");
+ test("a/../b")
+ .relativize("a/../b", "")
+ .relativize("a/..", "..")
+ .relativize("", "..")
+ .relativize(".", "..")
+ .relativize("..", "../..")
+ .relativize("b", "")
+ .relativize("c", "../c")
+ .relativize("../c", "../../c")
+ .relativize("a/../b/c", "c")
+ .relativizeFail("/")
+ .relativizeFail("/x");
// normalize
test("/")
--- a/jdk/test/java/nio/file/WatchService/LotsOfCancels.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/file/WatchService/LotsOfCancels.java Mon Aug 29 08:53:32 2016 -0700
@@ -53,10 +53,11 @@
Path testDir = Paths.get(System.getProperty("test.dir", "."));
Path top = Files.createTempDirectory(testDir, "LotsOfCancels");
for (int i=1; i<=16; i++) {
+ int id = i;
Path dir = Files.createDirectory(top.resolve("dir-" + i));
WatchService watcher = FileSystems.getDefault().newWatchService();
- pool.submit(() -> handle(dir, watcher));
- pool.submit(() -> poll(watcher));
+ pool.submit(() -> handle(id, dir, watcher));
+ pool.submit(() -> poll(id, watcher));
}
} finally {
pool.shutdown();
@@ -74,7 +75,8 @@
* Stress the given WatchService, specifically the cancel method, in
* the given directory. Closes the WatchService when done.
*/
- static void handle(Path dir, WatchService watcher) {
+ static void handle(int id, Path dir, WatchService watcher) {
+ System.out.printf("begin handle %d%n", id);
try {
try {
Path file = dir.resolve("anyfile");
@@ -85,12 +87,15 @@
key.cancel();
}
} finally {
+ System.out.printf("WatchService %d closing ...%n", id);
watcher.close();
+ System.out.printf("WatchService %d closed %n", id);
}
} catch (Exception e) {
e.printStackTrace();
failed = true;
}
+ System.out.printf("end handle %d%n", id);
}
/**
@@ -98,7 +103,8 @@
* queue drained, it also hogs a CPU core which seems necessary to
* tickle the original bug.
*/
- static void poll(WatchService watcher) {
+ static void poll(int id, WatchService watcher) {
+ System.out.printf("begin poll %d%n", id);
try {
for (;;) {
WatchKey key = watcher.take();
@@ -108,10 +114,12 @@
}
}
} catch (ClosedWatchServiceException expected) {
- // nothing to do
+ // nothing to do but print
+ System.out.printf("poll %d expected exception %s%n", id, expected);
} catch (Exception e) {
e.printStackTrace();
failed = true;
}
+ System.out.printf("end poll %d%n", id);
}
}
--- a/jdk/test/java/nio/file/WatchService/UpdateInterference.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/nio/file/WatchService/UpdateInterference.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,9 @@
import static java.nio.file.StandardWatchEventKinds.*;
public class UpdateInterference {
+
+ private static volatile boolean stop;
+
public static void main(String[] args) throws IOException, InterruptedException {
final Path root = Files.createTempDirectory("test");
final Path foo = root.resolve("foo");
@@ -43,64 +46,89 @@
Files.createDirectory(bar);
Files.createDirectory(baz);
- final WatchService watcher = root.getFileSystem().newWatchService();
- final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
- final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
+ try (final WatchService watcher = root.getFileSystem().newWatchService()) {
+ final WatchKey fooKey = foo.register(watcher, ENTRY_CREATE);
+ final WatchKey barKey = bar.register(watcher, ENTRY_CREATE);
+
+ Thread t1 = null;
+ Thread t2 = null;
+ try {
+ t1 = new Thread() {
- new Thread() {
- { setDaemon(true); }
+ @Override
+ public void run() {
+ while (!stop) {
+ try {
+ final Path temp = Files.createTempFile(foo, "temp", ".tmp");
+ Files.delete(temp);
+ Thread.sleep(10);
+ } catch (IOException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ };
+
+ t2 = new Thread() {
- @Override
- public void run() {
- while (true) {
- try {
- final Path temp = Files.createTempFile(foo, "temp", ".tmp");
- Files.delete(temp);
- Thread.sleep(10);
- } catch (IOException | InterruptedException e) {
- throw new RuntimeException(e);
+ @Override
+ public void run() {
+ WatchKey bazKeys[] = new WatchKey[32];
+ while (!stop) {
+ try {
+ for( int i = 0; i < bazKeys.length; i++) {
+ bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
+ }
+ for( int i = 0; i < bazKeys.length; i++) {
+ bazKeys[i].cancel();
+ }
+ Thread.sleep(1);
+ } catch (IOException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
+ };
+
+ t1.start();
+ t2.start();
+
+ long time = System.currentTimeMillis();
+ while ((System.currentTimeMillis() - time) < 15000) {
+ final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
+ if (key == null) continue;
+
+ if (key != fooKey) {
+ List<WatchEvent<?>> pollEvents = key.pollEvents();
+ for (WatchEvent<?> watchEvent : pollEvents) {
+ System.out.println(watchEvent.count() + " " +
+ watchEvent.kind() + " " +
+ watchEvent.context());
+ }
+ throw new RuntimeException("Event received for unexpected key");
+ }
+ key.reset();
+ }
+ } finally {
+ // the threads should stop before WatchService is closed
+ // to avoid ClosedWatchServiceException
+ stop = true;
+
+ // wait for threads to finish
+ if (t1 != null) {
+ t1.join();
+ }
+
+ if (t2 != null) {
+ t2.join();
}
}
- }.start();
-
- new Thread() {
- { setDaemon(true); }
-
- @Override
- public void run() {
- WatchKey bazKeys[] = new WatchKey[32];
- while (true) {
- try {
- for( int i = 0; i < bazKeys.length; i++) {
- bazKeys[i] = baz.register(watcher, ENTRY_CREATE);
- }
- for( int i = 0; i < bazKeys.length; i++) {
- bazKeys[i].cancel();
- }
- Thread.sleep(1);
- } catch (IOException | InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }.start();
-
- long time = System.currentTimeMillis();
- while ((System.currentTimeMillis() - time) < 15000) {
- final WatchKey key = watcher.poll(60, TimeUnit.SECONDS);
- if (key == null) continue;
-
- if (key != fooKey) {
- List<WatchEvent<?>> pollEvents = key.pollEvents();
- for (WatchEvent<?> watchEvent : pollEvents) {
- System.out.println(watchEvent.count() + " " +
- watchEvent.kind() + " " +
- watchEvent.context());
- }
- throw new RuntimeException("Event received for unexpected key");
- }
- key.reset();
+ } finally {
+ // clean up
+ Files.delete(foo);
+ Files.delete(bar);
+ Files.delete(baz);
+ Files.delete(root);
}
}
}
--- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -419,6 +419,21 @@
ZoneOffset.ofHoursMinutesSeconds(-19, 0, 0);
}
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_factory_int_hours_minutes_seconds_minutesMinValue() {
+ ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, -1);
+ }
+
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_factory_int_hours_minutes_seconds_secondsMinValue() {
+ ZoneOffset.ofHoursMinutesSeconds(0, 0, Integer.MIN_VALUE);
+ }
+
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_factory_int_hours_minutes_seconds_minutesAndSecondsMinValue() {
+ ZoneOffset.ofHoursMinutesSeconds(0, Integer.MIN_VALUE, Integer.MIN_VALUE);
+ }
+
//-----------------------------------------------------------------------
@Test
public void test_factory_ofTotalSeconds() {
@@ -437,6 +452,11 @@
ZoneOffset.ofTotalSeconds(-18 * 60 * 60 - 1);
}
+ @Test(expectedExceptions=DateTimeException.class)
+ public void test_factory_ofTotalSeconds_minValue() {
+ ZoneOffset.ofTotalSeconds(Integer.MIN_VALUE);
+ }
+
//-----------------------------------------------------------------------
// from()
//-----------------------------------------------------------------------
--- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -360,6 +360,21 @@
}
/**
+ * Test keySet().removeAll on empty map
+ */
+ public void testKeySet_empty_removeAll() {
+ ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
+ Set<Integer> set = map.keySet();
+ set.removeAll(Collections.emptyList());
+ assertTrue(map.isEmpty());
+ assertTrue(set.isEmpty());
+ // following is test for JDK-8163353
+ set.removeAll(Collections.emptySet());
+ assertTrue(map.isEmpty());
+ assertTrue(set.isEmpty());
+ }
+
+ /**
* keySet.toArray returns contains all keys
*/
public void testKeySetToArray() {
--- a/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java Mon Aug 29 08:53:32 2016 -0700
@@ -80,7 +80,7 @@
}
try (JarFile jf = new JarFile(multirelease)) {
- Assert.assertFalse(jf.isMultiRelease());
+ Assert.assertTrue(jf.isMultiRelease());
}
try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Runtime.version())) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/CryptoPermissions/TestUnlimited.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8061842
+ * @summary Package jurisdiction policy files as something other than JAR
+ * @run main/othervm TestUnlimited "" exception
+ * @run main/othervm TestUnlimited limited fail
+ * @run main/othervm TestUnlimited unlimited pass
+ * @run main/othervm TestUnlimited unlimited/ pass
+ * @run main/othervm TestUnlimited NosuchDir exception
+ * @run main/othervm TestUnlimited . exception
+ * @run main/othervm TestUnlimited /tmp/unlimited exception
+ * @run main/othervm TestUnlimited ../policy/unlimited exception
+ * @run main/othervm TestUnlimited ./unlimited exception
+ * @run main/othervm TestUnlimited /unlimited exception
+ */
+import javax.crypto.*;
+import java.security.Security;
+
+public class TestUnlimited {
+
+ public static void main(String[] args) throws Exception {
+ /*
+ * Override the Security property to allow for unlimited policy.
+ * Would need appropriate permissions if Security Manager were
+ * active.
+ */
+ if (args.length != 2) {
+ throw new Exception("Two args required");
+ }
+
+ boolean expected = args[1].equals("pass");
+ boolean exception = args[1].equals("exception");
+ boolean result = false;
+
+ System.out.println("Testing: " + args[0]);
+
+ if (args[0].equals("\"\"")) {
+ Security.setProperty("crypto.policy", "");
+ } else {
+ Security.setProperty("crypto.policy", args[0]);
+ }
+
+ /*
+ * Use the AES as the test Cipher
+ * If there is an error initializing, we will never get past here.
+ */
+ try {
+ int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
+ System.out.println("max AES key len:" + maxKeyLen);
+ if (maxKeyLen > 128) {
+ System.out.println("Unlimited policy is active");
+ result = true;
+ } else {
+ System.out.println("Unlimited policy is NOT active");
+ result = false;
+ }
+ } catch (Throwable e) {
+ if (!exception) {
+ throw new Exception();
+ }
+ }
+
+ System.out.println(
+ "Expected:\t" + expected + "\nResult:\t\t" + result);
+ if (expected != result) {
+ throw new Exception();
+ }
+
+ System.out.println("DONE!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/crypto/dsig/SecureValidationPolicy.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8151893
+ * @summary Tests for the jdk.xml.dsig.secureValidationPolicy security property
+ * @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom
+ */
+
+import java.security.Security;
+import java.util.List;
+import org.jcp.xml.dsig.internal.dom.Policy;
+
+public class SecureValidationPolicy {
+
+ public static void main(String[] args) throws Exception {
+
+ List<String> restrictedSchemes = List.of("file:/tmp/foo",
+ "http://java.com", "https://java.com");
+ List<String> restrictedAlgs = List.of(
+ "http://www.w3.org/TR/1999/REC-xslt-19991116",
+ "http://www.w3.org/2001/04/xmldsig-more#rsa-md5",
+ "http://www.w3.org/2001/04/xmldsig-more#hmac-md5",
+ "http://www.w3.org/2001/04/xmldsig-more#md5");
+
+ // Test expected defaults
+ System.out.println("Testing defaults");
+ if (!Policy.restrictNumTransforms(6)) {
+ throw new Exception("maxTransforms not enforced");
+ }
+ if (!Policy.restrictNumReferences(31)) {
+ throw new Exception("maxReferences not enforced");
+ }
+ for (String scheme : restrictedSchemes) {
+ if (!Policy.restrictReferenceUriScheme(scheme)) {
+ throw new Exception(scheme + " scheme not restricted");
+ }
+ }
+ for (String alg : restrictedAlgs) {
+ if (!Policy.restrictAlg(alg)) {
+ throw new Exception(alg + " alg not restricted");
+ }
+ }
+ if (!Policy.restrictDuplicateIds()) {
+ throw new Exception("noDuplicateIds not enforced");
+ }
+ if (!Policy.restrictRetrievalMethodLoops()) {
+ throw new Exception("noRetrievalMethodLoops not enforced");
+ }
+ }
+}
--- a/jdk/test/jdk/lambda/TEST.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/lambda/TEST.properties Mon Aug 29 08:53:32 2016 -0700
@@ -3,4 +3,4 @@
TestNG.dirs = .
javatest.maxOutputSize = 250000
-modules = jdk.compiler
+modules = jdk.compiler jdk.zipfs
--- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @summary Verify the defining class loader of each module never delegates
* to its child class loader. Also sanity check java.compact2
* requires.
+ * @modules java.compact2
* @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation
*/
@@ -33,7 +34,9 @@
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
import java.util.Set;
+import static java.util.stream.Collectors.toSet;
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
@@ -58,8 +61,9 @@
.requires(Set.of(PUBLIC), "java.xml")
.build();
- private static final Set<ModuleReference> MREFS
- = ModuleFinder.ofSystem().findAll();
+ private static final Set<ModuleDescriptor> MREFS
+ = Layer.boot().modules().stream().map(Module::getDescriptor)
+ .collect(toSet());
private void check(ModuleDescriptor md, ModuleDescriptor ref) {
assertTrue(md.requires().size() == ref.requires().size());
@@ -69,7 +73,7 @@
@Test
public void checkJavaBase() {
ModuleDescriptor md =
- MREFS.stream().map(ModuleReference::descriptor)
+ MREFS.stream()
.filter(d -> d.name().equals(JAVA_BASE))
.findFirst().orElseThrow(Error::new);
@@ -78,7 +82,7 @@
@Test
public void checkCompact2() {
ModuleDescriptor md =
- MREFS.stream().map(ModuleReference::descriptor)
+ MREFS.stream()
.filter(d -> d.name().equals(JAVA_COMPACT2))
.findFirst().orElseThrow(Error::new);
check(md, COMPACT2);
@@ -87,7 +91,7 @@
@Test
public void checkLoaderDelegation() {
Layer boot = Layer.boot();
- MREFS.stream().map(ModuleReference::descriptor)
+ MREFS.stream()
.forEach(md -> md.requires().stream().forEach(req ->
{
// check if M requires D and D's loader must be either the
--- a/jdk/test/jdk/modules/scenarios/container/ContainerTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/modules/scenarios/container/ContainerTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,6 +26,8 @@
* @library /lib/testlibrary
* @modules jdk.jartool/sun.tools.jar
* jdk.compiler
+ * jdk.zipfs
+ * java.se
* @build ContainerTest CompilerUtils jdk.testlibrary.*
* @run testng ContainerTest
* @summary Starts a simple container that uses dynamic configurations
--- a/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/nio/zipfs/MultiReleaseJarTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,7 +28,7 @@
* @library /lib/testlibrary/java/util/jar
* @build Compiler JarBuilder CreateMultiReleaseTestJars
* @run testng MultiReleaseJarTest
- * @modules java.compiler
+ * @modules jdk.compiler
* jdk.jartool
* jdk.zipfs
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/JFSTester.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164389
+ * @summary walk entries in a jdk.nio.zipfs.JarFileSystem
+ * @modules jdk.jartool/sun.tools.jar
+ * @run testng JFSTester
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class JFSTester {
+ private URI jarURI;
+ private Path jarfile;
+
+ @BeforeClass
+ public void initialize() throws Exception {
+ String userdir = System.getProperty("user.dir",".");
+ jarfile = Paths.get(userdir, "test.jar");
+ String srcdir = System.getProperty("test.src");
+ String[] args = (
+ "-cf "
+ + jarfile.toString()
+ + " -C "
+ + srcdir
+ + " root --release 9 -C "
+ + srcdir
+ + System.getProperty("file.separator")
+ + "v9 root"
+ ).split(" +");
+ new sun.tools.jar.Main(System.out, System.err, "jar").run(args);
+ String ssp = jarfile.toUri().toString();
+ jarURI = new URI("jar", ssp, null);
+ }
+
+ @AfterClass
+ public void close() throws IOException {
+ Files.deleteIfExists(jarfile);
+ }
+
+ @Test
+ public void testWalk() throws IOException {
+
+ // no configuration, treat multi-release jar as unversioned
+ Map<String,String> env = new HashMap<>();
+ Set<String> contents = doTest(env);
+ Set<String> baseContents = Set.of(
+ "This is leaf 1.\n",
+ "This is leaf 2.\n",
+ "This is leaf 3.\n",
+ "This is leaf 4.\n"
+ );
+ Assert.assertEquals(contents, baseContents);
+
+ // a configuration and jar file is multi-release
+ env.put("multi-release", "9");
+ contents = doTest(env);
+ Set<String> versionedContents = Set.of(
+ "This is versioned leaf 1.\n",
+ "This is versioned leaf 2.\n",
+ "This is versioned leaf 3.\n",
+ "This is versioned leaf 4.\n"
+ );
+ Assert.assertEquals(contents, versionedContents);
+ }
+
+ private Set<String> doTest(Map<String,String> env) throws IOException {
+ Set<String> contents;
+ try (FileSystem fs = FileSystems.newFileSystem(jarURI, env)) {
+ Path root = fs.getPath("root");
+ contents = Files.walk(root)
+ .filter(p -> !Files.isDirectory(p))
+ .map(this::pathToContents)
+ .collect(Collectors.toSet());
+ }
+ return contents;
+ }
+
+ private String pathToContents(Path path) {
+ try {
+ return new String(Files.readAllBytes(path));
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf1.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is leaf 1.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir1/leaf2.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is leaf 2.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf3.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is leaf 3.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/root/dir2/leaf4.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is leaf 4.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf1.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is versioned leaf 1.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir1/leaf2.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is versioned leaf 2.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf3.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is versioned leaf 3.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/nio/zipfs/jarfs/v9/root/dir2/leaf4.txt Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1 @@
+This is versioned leaf 4.
--- a/jdk/test/jdk/security/JavaDotSecurity/final_java_security Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/security/JavaDotSecurity/final_java_security Mon Aug 29 08:53:32 2016 -0700
@@ -10,6 +10,7 @@
foo.6=9a
foo.7=10
foo.8=12
+crypto.policy=somepolicy
package.access=sun.,\
solaris.,\
--- a/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh Mon Aug 29 08:53:32 2016 -0700
@@ -46,7 +46,13 @@
fi
$JAVAC -d . $TOOLSRC
-$JAVA $TOOLNAME $TESTSRC/raw_java_security outfile solaris sparc $TESTSRC/more_restricted
+$JAVA $TOOLNAME \
+ $TESTSRC/raw_java_security \
+ outfile \
+ solaris \
+ sparc \
+ somepolicy \
+ $TESTSRC/more_restricted
# On Windows, line end could be different. -b is a cross-platform option.
-diff -b outfile $TESTSRC/final_java_security
\ No newline at end of file
+diff -b outfile $TESTSRC/final_java_security
--- a/jdk/test/jdk/security/JavaDotSecurity/raw_java_security Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/security/JavaDotSecurity/raw_java_security Mon Aug 29 08:53:32 2016 -0700
@@ -44,6 +44,7 @@
#ifndef macosx-x64
foo.tbd=12
#endif
+crypto.policy=crypto.policydir-tbd
package.access=sun.,\
#ifdef solaris
--- a/jdk/test/jdk/security/jarsigner/Spec.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/jdk/security/jarsigner/Spec.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.provider.certpath
* jdk.jartool
+ * jdk.crypto.ec
*/
import com.sun.jarsigner.ContentSigner;
--- a/jdk/test/sun/security/krb5/auto/BadKdc1.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/sun/security/krb5/auto/BadKdc1.java Mon Aug 29 08:53:32 2016 -0700
@@ -44,16 +44,16 @@
}
BadKdc.go(
- "121212222222(32){1,2}1222(32){1,2}", // 1 2
+ "121212222222(32){1,3}1222(32){1,3}", // 1 2
// The above line means try kdc1 for 2 seconds then kdc1
// for 2 seconds... finally kdc3 for 2 seconds.
- "1222(32){1,2}1222(32){1,2}", // 1 2
+ "1222(32){1,3}1222(32){1,3}", // 1 2
// refresh
- "121212222222(32){1,2}1222(32){1,2}", // 1 2
+ "121212222222(32){1,3}1222(32){1,3}", // 1 2
// k3 off k2 on
- "(122212(22){1,2}|1222323232-)", // 1
+ "(122212(22){1,3}|1222323232-)", // 1
// k1 on
- "(12(12){1,2}|122212|122232-)" // empty
+ "(12(12){1,3}|122212|122232-)" // empty
);
}
}
--- a/jdk/test/sun/security/krb5/auto/BadKdc2.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/sun/security/krb5/auto/BadKdc2.java Mon Aug 29 08:53:32 2016 -0700
@@ -42,14 +42,14 @@
Security.setProperty(
"krb5.kdc.bad.policy", "tryLess:2," + BadKdc.toReal(1000));
BadKdc.go(
- "121212222222(32){1,2}11112121(32){1,2}", // 1 2
- "11112121(32){1,2}11112121(32){1,2}", // 1 2
+ "121212222222(32){1,3}11112121(32){1,3}", // 1 2
+ "11112121(32){1,3}11112121(32){1,3}", // 1 2
// refresh
- "121212222222(32){1,2}11112121(32){1,2}", // 1 2
+ "121212222222(32){1,3}11112121(32){1,3}", // 1 2
// k3 off k2 on
- "1111(21){1,2}1111(22){1,2}", // 1
+ "1111(21){1,3}1111(22){1,3}", // 1
// k1 on
- "(11){1,2}(12){1,2}" // empty
+ "(11){1,3}(12){1,3}" // empty
);
}
}
--- a/jdk/test/sun/security/krb5/auto/BadKdc4.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/sun/security/krb5/auto/BadKdc4.java Mon Aug 29 08:53:32 2016 -0700
@@ -37,12 +37,12 @@
throws Exception {
Security.setProperty("krb5.kdc.bad.policy", "");
BadKdc.go(
- "121212222222(32){1,2}121212222222(32){1,2}",
- "121212222222(32){1,2}121212222222(32){1,2}",
+ "121212222222(32){1,3}121212222222(32){1,3}",
+ "121212222222(32){1,3}121212222222(32){1,3}",
// refresh
- "121212222222(32){1,2}121212222222(32){1,2}",
+ "121212222222(32){1,3}121212222222(32){1,3}",
// k3 off k2 on
- "121212(22){1,2}121212(22){1,2}",
+ "121212(22){1,3}121212(22){1,3}",
// k1 on
"(12){2,4}"
);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/KdcPolicy.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.*;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.security.auth.login.LoginException;
+import sun.security.krb5.Asn1Exception;
+import sun.security.krb5.Config;
+
+/*
+ * @test
+ * @bug 8164656
+ * @run main/othervm KdcPolicy udp
+ * @run main/othervm KdcPolicy tcp
+ * @summary krb5.kdc.bad.policy test
+ */
+public class KdcPolicy {
+
+ // Is this test on UDP?
+ static boolean udp;
+
+ public static void main(String[] args) throws Exception {
+
+ udp = args[0].equals("udp");
+
+ try {
+ main0();
+ } catch (LoginException le) {
+ Throwable cause = le.getCause();
+ if (cause instanceof Asn1Exception) {
+ System.out.println("Another process sends a packet to " +
+ "this server. Ignored.");
+ return;
+ }
+ throw le;
+ }
+ }
+
+ static DebugMatcher cm = new DebugMatcher();
+
+ static void main0() throws Exception {
+
+ System.setProperty("sun.security.krb5.debug", "true");
+
+ // One real KDC. Must be created before fake KDCs
+ // to read the TestHosts file.
+ OneKDC kdc = new OneKDC(null);
+
+ // Two fake KDCs, d1 and d2 only listen but do not respond.
+
+ if (udp) {
+ try (DatagramSocket d1 = new DatagramSocket();
+ DatagramSocket d2 = new DatagramSocket()) {
+ run(d1.getLocalPort(), d2.getLocalPort(), kdc.getPort());
+ }
+ } else {
+ try (ServerSocket d1 = new ServerSocket(0);
+ ServerSocket d2 = new ServerSocket(0)) {
+ run(d1.getLocalPort(), d2.getLocalPort(), kdc.getPort());
+ }
+ }
+ }
+
+ static void run(int p1, int p2, int p3) throws Exception {
+
+ // cm.kdc() will return a and b for fake KDCs, and c for real KDC.
+ cm.addPort(-1).addPort(p1).addPort(p2).addPort(p3);
+
+ System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
+
+ // Check default timeout is 30s. Use real KDC only, otherwise too
+ // slow to wait for timeout.
+ writeConf(-1, -1, p3);
+ test("c30000c30000");
+
+ // 1. Default policy is tryLast
+ //Security.setProperty("krb5.kdc.bad.policy", "tryLast");
+
+ // Need a real KDC, otherwise there is no last good.
+ // This test waste 3 seconds waiting for d1 to timeout.
+ // It is possible the real KDC cannot fulfil the request
+ // in 3s, so it might fail (either 1st time or 2nd time).
+ writeConf(1, 3000, p1, p3);
+ test("a3000c3000c3000|a3000c3000-|a3000c3000c3000-");
+
+ // If a test case won't use a real KDC, it can be sped up.
+ writeConf(3, 5, p1, p2);
+ test("a5a5a5b5b5b5-"); // default max_retries == 3
+ test("a5a5a5b5b5b5-"); // all bad means no bad
+
+ // 2. No policy.
+ Security.setProperty("krb5.kdc.bad.policy", "");
+ Config.refresh();
+
+ // This case needs a real KDC, otherwise, all bad means no
+ // bad and we cannot tell the difference. This case waste 3
+ // seconds on d1 to timeout twice. It is possible the real KDC
+ // cannot fulfil the request within 3s, so it might fail
+ // (either 1st time or 2nd time).
+ writeConf(1, 3000, p1, p3);
+ test("a3000c3000a3000c3000|a3000c3000-|a3000c3000a3000c3000-");
+
+ // 3. tryLess with no argument means tryLess:1,5000
+ Security.setProperty("krb5.kdc.bad.policy", "tryLess");
+
+ // This case will waste 11s. We are checking that the default
+ // value of 5000 in tryLess is only used if it's less than timeout
+ // in krb5.conf
+ writeConf(1, 6000, p1);
+ test("a6000-"); // timeout in krb5.conf is 6s
+ test("a5000-"); // tryLess to 5s. This line can be made faster if
+ // d1 is a read KDC, but we have no existing method
+ // to start KDC on an existing ServerSocket (port).
+
+ writeConf(-1, 4, p1, p2);
+ test("a4a4a4b4b4b4-"); // default max_retries == 3
+ test("a4b4-"); // tryLess to 1. And since 4 < 5000, use 4.
+ Config.refresh();
+ test("a4a4a4b4b4b4-");
+
+ writeConf(5, 4, p1, p2);
+ test("a4a4a4a4a4b4b4b4b4b4-"); // user-provided max_retries == 5
+ test("a4b4-");
+ Config.refresh();
+ test("a4a4a4a4a4b4b4b4b4b4-");
+
+ // 3. tryLess with arguments
+ Security.setProperty("krb5.kdc.bad.policy",
+ "tryLess:2,5");
+
+ writeConf(-1, 6, p1, p2);
+ test("a6a6a6b6b6b6-"); // default max_retries == 3
+ test("a5a5b5b5-"); // tryLess to 2
+ Config.refresh();
+ test("a6a6a6b6b6b6-");
+
+ writeConf(5, 4, p1, p2);
+ test("a4a4a4a4a4b4b4b4b4b4-"); // user-provided max_retries == 5
+ test("a4a4b4b4-"); // tryLess to 2
+ Config.refresh();
+ test("a4a4a4a4a4b4b4b4b4b4-");
+ }
+
+ /**
+ * Writes a krb5.conf file.
+ * @param max max_retries, -1 if not set
+ * @param to kdc_timeout, -1 if not set
+ * @param ports where KDCs listen on
+ */
+ static void writeConf(int max, int to, int... ports) throws Exception {
+
+ // content of krb5.conf
+ String conf = "";
+
+ // Extra settings in [libdefaults]
+ String inDefaults = "";
+
+ // Extra settings in [realms]
+ String inRealm = "";
+
+ // We will randomly put extra settings only in [libdefaults],
+ // or in [realms] but with different values in [libdefaults],
+ // to prove that settings in [realms] override those in [libdefaults].
+ Random r = new Random();
+
+ if (max > 0) {
+ if (r.nextBoolean()) {
+ inDefaults += "max_retries = " + max + "\n";
+ } else {
+ inRealm += " max_retries = " + max + "\n";
+ inDefaults += "max_retries = " + (max + 1) + "\n";
+ }
+ }
+
+ if (to > 0) {
+ if (r.nextBoolean()) {
+ inDefaults += "kdc_timeout = " + to + "\n";
+ } else {
+ inRealm += " kdc_timeout = " + to + "\n";
+ inDefaults += "kdc_timeout = " + (to + 1) + "\n";
+ }
+ }
+
+ if (udp) {
+ if (r.nextBoolean()) {
+ inDefaults += "udp_preference_limit = 10000\n";
+ } else if (r.nextBoolean()) {
+ inRealm += " udp_preference_limit = 10000\n";
+ inDefaults += "udp_preference_limit = 1\n";
+ } // else no settings means UDP
+ } else {
+ if (r.nextBoolean()) {
+ inDefaults += "udp_preference_limit = 1\n";
+ } else {
+ inRealm += " udp_preference_limit = 1\n";
+ inDefaults += "udp_preference_limit = 10000\n";
+ }
+ }
+
+ conf = "[libdefaults]\n" +
+ "default_realm = " + OneKDC.REALM + "\n" +
+ inDefaults +
+ "\n" +
+ "[realms]\n" +
+ OneKDC.REALM + " = {\n";
+
+ for (int port : ports) {
+ conf += " kdc = " + OneKDC.KDCHOST + ":" + port + "\n" +
+ inRealm;
+ }
+
+ conf += "}\n";
+
+ Files.write(Paths.get("alternative-krb5.conf"), conf.getBytes());
+ Config.refresh();
+ }
+
+ /**
+ * One call of krb5 login. As long as the result matches one of expected,
+ * the test is considered as success. The grammar of expected is
+ *
+ * kdc#, timeout, kdc#, timeout, ..., optional "-" for failure
+ */
+ static void test(String... expected) throws Exception {
+
+ System.out.println("------------------TEST----------------------");
+ PrintStream oldOut = System.out;
+ boolean failed = false;
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(bo));
+ try {
+ Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+ } catch (Exception e) {
+ failed = true;
+ } finally {
+ System.setOut(oldOut);
+ }
+
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ StringBuilder sb = new StringBuilder();
+ for (String line: lines) {
+ if (cm.match(line)) {
+ if (udp != cm.isUDP()) {
+ sb.append("x");
+ }
+ sb.append(cm.kdc()).append(cm.timeout());
+ }
+ }
+ if (failed) sb.append('-');
+
+ String output = sb.toString();
+
+ boolean found = false;
+ for (String ex : expected) {
+ if (output.matches(ex)) {
+ System.out.println("Expected: " + ex + ", actual " + output);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ System.out.println("--------------- ERROR START -------------");
+ System.out.println(new String(bo.toByteArray()));
+ System.out.println("--------------- ERROR END ---------------");
+ throw new Exception("Does not match. Output is " + output);
+ }
+ }
+
+ /**
+ * A helper class to match the krb5 debug output:
+ * >>> KDCCommunication: kdc=host UDP:11555, timeout=200,Attempt =1, #bytes=138
+ *
+ * Example:
+ * DebugMatcher cm = new DebugMatcher();
+ * cm.addPort(12345).addPort(11555);
+ * for (String line : debugOutput) {
+ * if (cm.match(line)) {
+ * System.out.printf("%c%d\n", cm.kdc(), cm.timeout());
+ * // shows b200 for the example above
+ * }
+ * }
+ */
+ static class DebugMatcher {
+
+ static final Pattern re = Pattern.compile(
+ ">>> KDCCommunication: kdc=\\S+ (TCP|UDP):(\\d+), " +
+ "timeout=(\\d+),Attempt\\s*=(\\d+)");
+
+ List<Integer> kdcPorts = new ArrayList<>();
+ Matcher matcher;
+
+ /**
+ * Add KDC ports one by one. See {@link #kdc()}.
+ */
+ DebugMatcher addPort(int port) {
+ if (port > 0) {
+ kdcPorts.add(port);
+ } else {
+ kdcPorts.clear();
+ }
+ return this;
+ }
+
+ /**
+ * When a line matches the ">>> KDCCommunication:" pattern. After a
+ * match, the getters below can be called on this match.
+ */
+ boolean match(String line) {
+ matcher = re.matcher(line);
+ return matcher.find();
+ }
+
+ /**
+ * Protocol of this match, "UDP" or "TCP".
+ */
+ boolean isUDP() {
+ return matcher.group(1).equals("UDP");
+ }
+
+ /**
+ * KDC for this match, "a" for the one 1st added bt addPort(), "b"
+ * for second, etc. Undefined for not added.
+ */
+ char kdc() {
+ int port = Integer.parseInt(matcher.group(2));
+ return (char) (kdcPorts.indexOf(port) + 'a');
+ }
+
+ /**
+ * Timeout value for this match.
+ */
+ int timeout() {
+ return Integer.parseInt(matcher.group(3));
+ }
+ }
+}
--- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -107,6 +107,38 @@
}
}
+ public static void launchJStack() throws IOException {
+
+ if (Platform.isOSX()) {
+ // Coredump stackwalking is not implemented for Darwin
+ System.out.println("This test is not expected to work on OS X. Skipping");
+ return;
+ }
+
+ System.out.println("Starting LingeredApp");
+ try {
+ theApp = LingeredApp.startApp(Arrays.asList("-Xmx256m"));
+
+ System.out.println("Starting jstack against " + theApp.getPid());
+ JDKToolLauncher launcher = createSALauncher();
+
+ launcher.addToolArg("jstack");
+ launcher.addToolArg("--pid=" + Long.toString(theApp.getPid()));
+
+ ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);;
+ output.shouldContain("No deadlocks found");
+ output.shouldNotContain("illegal bci");
+ output.shouldNotContain("AssertionFailure");
+ output.shouldHaveExitValue(0);
+
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ LingeredApp.stopApp(theApp);
+ }
+ }
+
/**
*
* @param vmArgs - vm and java arguments to launch test app
@@ -151,19 +183,6 @@
Arrays.asList(toolArgs));
}
- public static void launchNotOSX(String expectedMessage,
- String unexpectedMessage, String... toolArgs)
- throws IOException {
-
- if (Platform.isOSX()) {
- // Coredump stackwalking is not implemented for Darwin
- System.out.println("This test is not expected to work on OS X. Skipping");
- return;
- }
-
- launch(expectedMessage, unexpectedMessage, toolArgs);
- }
-
public static void testHeapDump() throws IOException {
File dump = new File("jhsdb.jmap.dump." +
System.currentTimeMillis() + ".hprof");
@@ -191,7 +210,7 @@
launchCLHSDB();
launch("compiler detected", null, "jmap", "--clstats");
- launchNotOSX("No deadlocks found", null, "jstack");
+ launchJStack();
launch("compiler detected", null, "jmap");
launch("Java System Properties",
"System Properties info not available", "jinfo");
--- a/jdk/test/tools/jlink/CustomPluginTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/tools/jlink/CustomPluginTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -67,6 +67,7 @@
testHelloProvider(helper, pluginModulePath);
testCustomPlugins(helper, pluginModulePath);
+ testModuleVerification(helper, pluginModulePath);
}
private void testCustomPlugins(Helper helper, Path pluginModulePath) {
@@ -93,8 +94,7 @@
String name = "customplugin";
Path src = Paths.get(System.getProperty("test.src")).resolve(name);
Path classes = helper.getJmodClassesDir().resolve(name);
- JImageGenerator.compile(src, classes,
- "--add-exports", "jdk.jlink/jdk.tools.jlink.internal=customplugin");
+ JImageGenerator.compile(src, classes);
return JImageGenerator.getJModTask()
.addClassPath(classes)
.jmod(helper.getJmodDir().resolve(name + ".jmod"))
@@ -136,4 +136,44 @@
throw new AssertionError("Custom plugin not called");
}
}
+
+ private void testModuleVerification(Helper helper, Path pluginModulePath) throws IOException {
+ {
+ // dependent module missing check
+ String moduleName = "bar"; // 8147491
+ Path jmodFoo = helper.generateDefaultJModule("foo").assertSuccess();
+ Path jmodBar = helper.generateDefaultJModule(moduleName, "foo").assertSuccess();
+ // rogue filter removes "foo" module resources which are
+ // required by "bar" module. Module checks after plugin
+ // application should detect and report error.
+ JImageGenerator.getJLinkTask()
+ .modulePath(helper.defaultModulePath())
+ .pluginModulePath(pluginModulePath)
+ .output(helper.createNewImageDir(moduleName))
+ .addMods(moduleName)
+ .option("--rogue-filter")
+ .option("/foo/")
+ .call()
+ .assertFailure("java.lang.module.ResolutionException");
+ }
+
+ {
+ // package exported by one module used as concealed package
+ // in another module. But, module-info.class is not updated!
+ String moduleName = "jdk.scripting.nashorn";
+ JImageGenerator.getJLinkTask()
+ .modulePath(helper.defaultModulePath())
+ .pluginModulePath(pluginModulePath)
+ .output(helper.createNewImageDir(moduleName))
+ .addMods(moduleName)
+ // "java.logging" includes a package 'javax.script'
+ // which is an exported package from "java.scripting" module!
+ // module-info.class of java.logging left "as is".
+ .option("--rogue-adder")
+ .option("/java.logging/javax/script/Foo.class")
+ .call()
+ .assertFailure(
+ "Module java.logging's descriptor returns inconsistent package set");
+ }
+ }
}
--- a/jdk/test/tools/jlink/ImageFileCreatorTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/tools/jlink/ImageFileCreatorTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -220,7 +220,7 @@
};
ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(),
- null);
+ null, false);
ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack);
}
--- a/jdk/test/tools/jlink/customplugin/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/tools/jlink/customplugin/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,4 +25,6 @@
requires jdk.jlink;
provides jdk.tools.jlink.plugin.Plugin with plugin.HelloPlugin;
provides jdk.tools.jlink.plugin.Plugin with plugin.CustomPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with plugin.RogueAdderPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with plugin.RogueFilterPlugin;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/customplugin/plugin/RogueAdderPlugin.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.Function;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
+import jdk.tools.jlink.plugin.Plugin;
+
+/**
+ * Rogue adder plugin
+ */
+public final class RogueAdderPlugin implements Plugin {
+ public static final String NAME = "rogue-adder";
+ private String resName;
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy(Function.identity(), out);
+ out.add(ResourcePoolEntry.create(resName, new byte[1]));
+ return out.build();
+ }
+
+ @Override
+ public String getDescription() {
+ return NAME + "-description";
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ resName = config.get(NAME);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/customplugin/plugin/RogueFilterPlugin.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Collections;
+import java.util.Map;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.Plugin;
+
+/**
+ * Rogue filter plugin
+ */
+public final class RogueFilterPlugin implements Plugin {
+ public static final String NAME = "rogue-filter";
+ private String prefix;
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy((file) -> {
+ return file.path().startsWith(prefix)? null : file;
+ }, out);
+ return out.build();
+ }
+
+ @Override
+ public String getDescription() {
+ return NAME + "-description";
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ prefix = config.get(NAME);
+ }
+}
--- a/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/tools/jlink/plugins/GenerateJLIClassesPluginTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -73,47 +73,6 @@
classFilesForSpecies(GenerateJLIClassesPlugin.defaultSpecies()),
List.of());
-
- // Test a valid set of options
- result = JImageGenerator.getJLinkTask()
- .modulePath(helper.defaultModulePath())
- .output(helper.createNewImageDir("generate-jli"))
- .option("--generate-jli-classes=bmh:bmh-species=LL,L3")
- .addMods("java.base")
- .call();
-
- image = result.assertSuccess();
-
- JImageValidator.validate(
- image.resolve("lib").resolve("modules"),
- classFilesForSpecies(List.of("LL", "L3")),
- classFilesForSpecies(List.of("L4")));
-
-
- // Test disabling BMH species generation
- result = JImageGenerator.getJLinkTask()
- .modulePath(helper.defaultModulePath())
- .output(helper.createNewImageDir("generate-jli"))
- .option("--generate-jli-classes=not-bmh:bmh-species=LL,L3")
- .addMods("java.base")
- .call();
-
- image = result.assertSuccess();
- JImageValidator.validate(
- image.resolve("lib").resolve("modules"),
- List.of(),
- classFilesForSpecies(List.of("LL", "L3", "L4")));
-
-
- // Test an invalid set of options
- result = JImageGenerator.getJLinkTask()
- .modulePath(helper.defaultModulePath())
- .output(helper.createNewImageDir("generate-jli"))
- .option("--generate-jli-classes=bmh:bmh-species=LL,L7V")
- .addMods("java.base")
- .call();
-
- result.assertFailure();
}
private static List<String> classFilesForSpecies(List<String> species) {
--- a/jdk/test/tools/launcher/VersionCheck.java Wed Jul 20 15:07:48 2016 +0200
+++ b/jdk/test/tools/launcher/VersionCheck.java Mon Aug 29 08:53:32 2016 -0700
@@ -82,6 +82,7 @@
"jcmd",
"jconsole",
"jcontrol",
+ "jdeprscan",
"jdeps",
"jimage",
"jinfo",
--- a/langtools/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -374,3 +374,4 @@
e181909291981038b041ed4d22714c4760e049cd jdk-9+129
3665ebc22a42c8f33777ee025ba0e300e6086a8c jdk-9+130
aebfafc43714d5a27d5064d8a0011eaccde633cf jdk-9+131
+2c17b65a37a8d7afdb9f96d5f11b28a3f21c78f2 jdk-9+132
--- a/langtools/make/build.xml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/build.xml Mon Aug 29 08:53:32 2016 -0700
@@ -246,10 +246,12 @@
<condition property="idea.target.jdk" value="${langtools.jdk.home}" else = "$JDKPath$">
<isset property="langtools.jdk.home"/>
</condition>
- <replace file=".idea/ant.xml" token="@IDEA_JTREG_HOME@" value="${idea.jtreg.home}"/>
<replace file=".idea/ant.xml" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
<replace dir=".idea/runConfigurations" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
<replace dir=".idea/runConfigurations" token="@XPATCH@" value="${xpatch.cmd}"/>
+ <replace file=".idea/misc.xml" token="@IDEA_JTREG_HOME@" value="${idea.jtreg.home}"/>
+ <replace file=".idea/misc.xml" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
+ <replace file=".idea/misc.xml" token="@XPATCH@" value="${xpatch.cmd}"/>
<mkdir dir=".idea/classes"/>
<javac source="${javac.build.source}"
target="${javac.build.target}"
--- a/langtools/make/intellij/ant.xml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/intellij/ant.xml Mon Aug 29 08:53:32 2016 -0700
@@ -3,10 +3,7 @@
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/.idea/build.xml">
<properties>
- <property name="jtreg.tests" value="$FilePath$" />
- <property name="langtools.jdk.home" value="@IDEA_TARGET_JDK@" />
- <property name="jtreg.home" value="@IDEA_JTREG_HOME@" />
- <property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=5900" />
+ <property name="langtools.jdk.home" value="@IDEA_TARGET_JDK@" />
</properties>
<executeOn event="afterCompilation" target="post-make" />
</buildFile>
--- a/langtools/make/intellij/build.xml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/intellij/build.xml Mon Aug 29 08:53:32 2016 -0700
@@ -8,32 +8,5 @@
<import file="../make/build.xml"/>
- <macrodef name="exec-target">
- <attribute name="antfile" default="${ant.file}" />
- <attribute name="target" />
- <sequential>
- <java classname="org.apache.tools.ant.Main" fork="true" spawn="true">
- <arg value="-f"/>
- <arg value="@{antfile}"/>
- <arg value="-Dlangtools.jdk.home=${langtools.jdk.home}"/>
- <arg value="-Djtreg.home=${jtreg.home}"/>
- <arg value="-Djtreg.tests=${jtreg.tests}"/>
- <arg value="-Djtreg.jpda.jvmargs=${jtreg.jpda.jvmargs}"/>
- <arg value="@{target}"/>
- <classpath>
- <pathelement path="${java.class.path}"/>
- </classpath>
- </java>
- </sequential>
- </macrodef>
-
<target name="post-make" depends="clean, build-all-tools"/>
-
- <target name="jtreg-debug" depends="build-all-tools, -def-jtreg">
- <exec-target target="jtreg-debug-internal"/>
- </target>
-
- <target name="jtreg-debug-internal" depends="-def-jtreg">
- <jtreg-tool name="all" tests="${jtreg.tests}" options="-conc:1" jpda.jvmargs="${jtreg.jpda.jvmargs}"/>
- </target>
</project>
--- a/langtools/make/intellij/langtools.iml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/intellij/langtools.iml Mon Aug 29 08:53:32 2016 -0700
@@ -7,7 +7,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/jdk.javadoc/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jdk.jdeps/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jdk.jshell/share/classes" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.compiler" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.javadoc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.jdeps" isTestSource="false" />
--- a/langtools/make/intellij/misc.xml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/intellij/misc.xml Mon Aug 29 08:53:32 2016 -0700
@@ -3,6 +3,13 @@
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
+ <component name="JTRegService">
+ <option name="JTRegDir" value="@IDEA_JTREG_HOME@" />
+ <option name="JTRegOptions" value='@XPATCH@' />
+ <option name="alternativeJrePath" value="@IDEA_TARGET_JDK@" />
+ <option name="alternativeJrePathEnabled" value="true" />
+ <option name="workDir" value="build" />
+ </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/.idea/out" />
</component>
--- a/langtools/make/intellij/runConfigurations/jtreg__debug_.xml Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<component name="ProjectRunConfigurationManager">
- <configuration default="false" name="jtreg (debug)" type="Remote" factoryName="Remote" singleton="true">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="true" />
- <option name="SHMEM_ADDRESS" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5900" />
- <RunnerSettings RunnerId="Debug">
- <option name="DEBUG_PORT" value="5900" />
- <option name="TRANSPORT" value="0" />
- <option name="LOCAL" value="false" />
- </RunnerSettings>
- <ConfigurationWrapper RunnerId="Debug" />
- <method>
- <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="jtreg-debug" />
- </method>
- </configuration>
-</component>
--- a/langtools/make/intellij/runConfigurations/jtreg__run_.xml Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<component name="ProjectRunConfigurationManager">
- <configuration default="false" name="jtreg (run)" type="AntRunConfiguration" factoryName="Ant Target">
- <antsettings antfile="file://$PROJECT_DIR$/.idea/build.xml" target="jtreg" />
- <method>
- <option name="Make" enabled="false" />
- </method>
- </configuration>
-</component>
--- a/langtools/make/intellij/utils/jtreg-live-templates.xml Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<!--
-The following live template declarations allow for automatic generation of jtreg test headers.
-Unfortunately, live templates cannot be shared on a per project base, but they can be easily imported
-by cutting and paste the following lines inside IntelliJ LiveTemplate settings (this will need to be done only once).
--->
-
-<template name="@test" value="@test * @bug $BUG_ID$ * @summary $BUG_SUMMARY$ * $JTREG_ACTION$ $FILE_NAME$" description="jtreg header (positive test)" toReformat="false" toShortenFQNames="true">
- <variable name="BUG_ID" expression="groovyScript("_1 ==~ /T\\d{7}/ ? _1.substring(1).take(7) : 'NNNNNNN'", fileNameWithoutExtension())" defaultValue="" alwaysStopAt="true" />
- <variable name="BUG_SUMMARY" expression=""Bug summary"" defaultValue="" alwaysStopAt="true" />
- <variable name="JTREG_ACTION" expression=""@compile"" defaultValue="" alwaysStopAt="true" />
- <variable name="FILE_NAME" expression="fileName()" defaultValue="" alwaysStopAt="true" />
- <context>
- <option name="JAVA_COMMENT" value="true" />
- </context>
-</template>
-<template name="@test /nodynamiccopyright/" value="@test * @bug $BUG_ID$ * @summary $BUG_SUMMARY$ * $JTREG_ACTION$/fail/ref=$GOLDEN_NAME$ -XDrawDiagnostics $FILE_NAME$" description="jtreg header (negative test)" toReformat="false" toShortenFQNames="true">
- <variable name="BUG_ID" expression="groovyScript("_1 ==~ /T\\d{7}/ ? _1.substring(1).take(7) : 'NNNNNNN'", fileNameWithoutExtension())" defaultValue="NNNNNNN" alwaysStopAt="true" />
- <variable name="BUG_SUMMARY" expression=""Bug summary"" defaultValue="" alwaysStopAt="true" />
- <variable name="JTREG_ACTION" expression=""@compile"" defaultValue="" alwaysStopAt="true" />
- <variable name="GOLDEN_NAME" expression="groovyScript("_1 + '.out'", fileNameWithoutExtension())" defaultValue="out.txt" alwaysStopAt="true" />
- <variable name="FILE_NAME" expression="fileName()" defaultValue="" alwaysStopAt="true" />
- <context>
- <option name="JAVA_COMMENT" value="true" />
- </context>
-</template>
--- a/langtools/make/intellij/workspace.xml Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/make/intellij/workspace.xml Mon Aug 29 08:53:32 2016 -0700
@@ -12,8 +12,6 @@
<filter targetName="build-all-tools" isVisible="true" />
<filter targetName="build-all-classes" isVisible="true" />
<filter targetName="clean" isVisible="true" />
- <filter targetName="jtreg" isVisible="true" />
- <filter targetName="jtreg-debug" isVisible="true" />
<filter targetName="crules" isVisible="true" />
</targetFilters>
<viewClosedWhenNoErrors value="true" />
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -160,7 +160,7 @@
* log all calls to {@linkplain JavaFileManager#flush}:
*
* <pre>
- * final {@linkplain java.util.logging.Logger Logger} logger = ...;
+ * final Logger logger = ...;
* {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
* JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
* StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
--- a/langtools/src/java.compiler/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/java.compiler/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,13 @@
* questions.
*/
+ /**
+ * Defines the Language Model, Annotation Processing, and Java Compiler APIs.
+ * <P>
+ * These APIs model declarations and types of the Java programming language,
+ * and define interfaces for tools such as compilers which can be invoked
+ * from a program.
+ */
module java.compiler {
exports javax.annotation.processing;
exports javax.lang.model;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ModuleTree;
import com.sun.source.tree.PackageTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
@@ -406,6 +407,12 @@
}
@Override @DefinedBy(Api.COMPILER_TREE)
+ public Void visitModule(ModuleTree tree, Void ignore) {
+ visitDecl(tree, null);
+ return super.visitModule(tree, ignore);
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
public Void visitVariable(VariableTree tree, Void ignore) {
visitDecl(tree, tree.getName());
return super.visitVariable(tree, ignore);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -210,7 +210,7 @@
AccessKind ak = AccessKind.PUBLIC;
for (TreePath p = path; p != null; p = p.getParentPath()) {
Element e = trees.getElement(p);
- if (e != null && e.getKind() != ElementKind.PACKAGE) {
+ if (e != null && e.getKind() != ElementKind.PACKAGE && e.getKind() != ElementKind.MODULE) {
ak = min(ak, AccessKind.of(e.getModifiers()));
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Mon Aug 29 08:53:32 2016 -0700
@@ -54,6 +54,7 @@
import static com.sun.tools.javac.tree.JCTree.Tag.ASSIGN;
import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
import static com.sun.tools.javac.tree.JCTree.Tag.NEWARRAY;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
/** Enter annotations onto symbols and types (and trees).
*
@@ -302,7 +303,6 @@
{
Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
Map<T, DiagnosticPosition> pos = new HashMap<>();
- boolean allowRepeatedAnnos = this.allowRepeatedAnnos;
for (List<JCAnnotation> al = withAnnotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
@@ -322,8 +322,7 @@
if (annotated.containsKey(a.type.tsym)) {
if (!allowRepeatedAnnos) {
- log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
- allowRepeatedAnnos = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), "repeatable.annotations.not.supported.in.source");
}
ListBuffer<T> l = annotated.get(a.type.tsym);
l = l.append(c);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Aug 29 08:53:32 2016 -0700
@@ -70,6 +70,7 @@
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.code.TypeTag.WILDCARD;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
/** This is the main context-dependent analysis phase in GJC. It
* encompasses name resolution, type checking and constant folding as
@@ -1282,13 +1283,9 @@
try {
boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
- boolean stringSwitch = false;
- if (types.isSameType(seltype, syms.stringType)) {
- if (allowStringsInSwitch) {
- stringSwitch = true;
- } else {
- log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
- }
+ boolean stringSwitch = types.isSameType(seltype, syms.stringType);
+ if (stringSwitch && !allowStringsInSwitch) {
+ log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
}
if (!enumSwitch && !stringSwitch)
seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
@@ -3484,7 +3481,7 @@
}
if (!allowStaticInterfaceMethods && sitesym.isInterface() &&
sym.isStatic() && sym.kind == MTH) {
- log.error(tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName);
+ log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName);
}
} else if (sym.kind != ERR &&
(sym.flags() & STATIC) != 0 &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Aug 29 08:53:32 2016 -0700
@@ -789,23 +789,25 @@
if (!TreeInfo.isDiamond(tree) ||
t.isErroneous()) {
return checkClassType(tree.clazz.pos(), t, true);
- } else if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
- log.error(tree.clazz.pos(),
- Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
- return types.createErrorType(t);
- } else if (t.tsym.type.getTypeArguments().isEmpty()) {
- log.error(tree.clazz.pos(),
- "cant.apply.diamond.1",
- t, diags.fragment("diamond.non.generic", t));
- return types.createErrorType(t);
- } else if (tree.typeargs != null &&
- tree.typeargs.nonEmpty()) {
- log.error(tree.clazz.pos(),
- "cant.apply.diamond.1",
- t, diags.fragment("diamond.and.explicit.params", t));
- return types.createErrorType(t);
} else {
- return t;
+ if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
+ log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
+ Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
+ }
+ if (t.tsym.type.getTypeArguments().isEmpty()) {
+ log.error(tree.clazz.pos(),
+ "cant.apply.diamond.1",
+ t, diags.fragment("diamond.non.generic", t));
+ return types.createErrorType(t);
+ } else if (tree.typeargs != null &&
+ tree.typeargs.nonEmpty()) {
+ log.error(tree.clazz.pos(),
+ "cant.apply.diamond.1",
+ t, diags.fragment("diamond.and.explicit.params", t));
+ return types.createErrorType(t);
+ } else {
+ return t;
+ }
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,7 +29,7 @@
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -118,4 +118,19 @@
return list;
}
}
+
+ private FileSystemProvider jarFSProvider;
+
+ public synchronized FileSystemProvider getJarFSProvider() {
+ if (jarFSProvider != null) {
+ return jarFSProvider;
+ }
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (provider.getScheme().equals("jar")) {
+ return (jarFSProvider = provider);
+ }
+ }
+ return null;
+ }
+
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Mon Aug 29 08:53:32 2016 -0700
@@ -69,6 +69,7 @@
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
+import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -509,7 +510,9 @@
this.archivePath = archivePath;
if (multiReleaseValue != null && archivePath.toString().endsWith(".jar")) {
Map<String,String> env = Collections.singletonMap("multi-release", multiReleaseValue);
- this.fileSystem = getJarFSProvider().newFileSystem(archivePath, env);
+ FileSystemProvider jarFSProvider = fsInfo.getJarFSProvider();
+ Assert.checkNonNull(jarFSProvider, "should have been caught before!");
+ this.fileSystem = jarFSProvider.newFileSystem(archivePath, env);
} else {
this.fileSystem = FileSystems.newFileSystem(archivePath, null);
}
@@ -597,20 +600,6 @@
}
}
- private FileSystemProvider jarFSProvider;
-
- private FileSystemProvider getJarFSProvider() throws IOException {
- if (jarFSProvider != null) {
- return jarFSProvider;
- }
- for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
- if (provider.getScheme().equals("jar")) {
- return (jarFSProvider = provider);
- }
- }
- throw new ProviderNotFoundException("no provider found for .jar files");
- }
-
/**
* container is a directory, a zip file, or a non-existent path.
*/
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Mon Aug 29 08:53:32 2016 -0700
@@ -42,6 +42,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
+import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -315,26 +316,30 @@
if (fsInfo.isFile(file)) {
/* File is an ordinary file. */
- if (!isArchive(file)
- && !file.getFileName().toString().endsWith(".jmod")
- && !file.endsWith("modules")) {
- /* Not a recognized extension; open it to see if
- it looks like a valid zip file. */
- try {
- // TODO: use of ZipFile should be updated
- ZipFile z = new ZipFile(file.toFile());
- z.close();
- if (warn) {
- log.warning(Lint.LintCategory.PATH,
- "unexpected.archive.file", file);
+ if ( !file.getFileName().toString().endsWith(".jmod")
+ && !file.endsWith("modules")) {
+ if (!isArchive(file)) {
+ /* Not a recognized extension; open it to see if
+ it looks like a valid zip file. */
+ try {
+ FileSystems.newFileSystem(file, null).close();
+ if (warn) {
+ log.warning(Lint.LintCategory.PATH,
+ "unexpected.archive.file", file);
+ }
+ } catch (IOException | ProviderNotFoundException e) {
+ // FIXME: include e.getLocalizedMessage in warning
+ if (warn) {
+ log.warning(Lint.LintCategory.PATH,
+ "invalid.archive.file", file);
+ }
+ return;
}
- } catch (IOException e) {
- // FIXME: include e.getLocalizedMessage in warning
- if (warn) {
- log.warning(Lint.LintCategory.PATH,
- "invalid.archive.file", file);
+ } else {
+ if (fsInfo.getJarFSProvider() == null) {
+ log.error(Errors.NoZipfsForArchive(file));
+ return ;
}
- return;
}
}
}
@@ -1054,6 +1059,9 @@
} catch (IOException e) {
log.error(Errors.LocnCantReadFile(p));
return null;
+ } catch (ProviderNotFoundException e) {
+ log.error(Errors.NoZipfsForArchive(p));
+ return null;
}
//automatic module:
@@ -1105,13 +1113,9 @@
fs.close();
}
}
- } catch (ProviderNotFoundException e) {
- // will be thrown if the file is not a valid zip file
- log.error(Errors.LocnCantReadFile(p));
- return null;
} catch (ModuleNameReader.BadClassFile e) {
log.error(Errors.LocnBadModuleInfo(p));
- } catch (IOException e) {
+ } catch (IOException | ProviderNotFoundException e) {
log.error(Errors.LocnCantReadFile(p));
return null;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Aug 29 08:53:32 2016 -0700
@@ -566,6 +566,11 @@
* class name is of the form module-name.module-info.
*/
Name readModuleInfoName(int i) {
+ if (majorVersion < Version.V53.major) {
+ throw badClassFile("anachronistic.module.info",
+ Integer.toString(majorVersion),
+ Integer.toString(minorVersion));
+ }
int classIndex = poolIdx[i];
if (buf[classIndex] == CONSTANT_Class) {
int utf8Index = poolIdx[getChar(classIndex + 1)];
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Aug 29 08:53:32 2016 -0700
@@ -51,6 +51,7 @@
import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
+import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
/** The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
@@ -2536,11 +2537,13 @@
finalizer = block();
}
} else {
- if (allowTWR) {
- if (resources.isEmpty())
+ if (resources.isEmpty()) {
+ if (allowTWR) {
error(pos, "try.without.catch.finally.or.resource.decls");
- } else
- error(pos, "try.without.catch.or.finally");
+ } else {
+ error(pos, "try.without.catch.or.finally");
+ }
+ }
}
return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
}
@@ -3238,6 +3241,8 @@
accept(SEMI);
defs.append(toP(F.at(pos).Uses(service)));
} else {
+ setErrorEndPos(pos);
+ reportSyntaxError(pos, "invalid.module.directive");
break;
}
}
@@ -4080,74 +4085,62 @@
void checkDiamond() {
if (!allowDiamond) {
- error(token.pos, "diamond.not.supported.in.source", source.name);
- allowDiamond = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "diamond.not.supported.in.source", source.name);
}
}
void checkMulticatch() {
if (!allowMulticatch) {
- error(token.pos, "multicatch.not.supported.in.source", source.name);
- allowMulticatch = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "multicatch.not.supported.in.source", source.name);
}
}
void checkTryWithResources() {
if (!allowTWR) {
- error(token.pos, "try.with.resources.not.supported.in.source", source.name);
- allowTWR = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "try.with.resources.not.supported.in.source", source.name);
}
}
void checkVariableInTryWithResources(int startPos) {
if (!allowEffectivelyFinalVariablesInTWR) {
- error(startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
- allowEffectivelyFinalVariablesInTWR = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
}
}
void checkLambda() {
if (!allowLambda) {
- log.error(token.pos, "lambda.not.supported.in.source", source.name);
- allowLambda = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "lambda.not.supported.in.source", source.name);
}
}
void checkMethodReferences() {
if (!allowMethodReferences) {
- log.error(token.pos, "method.references.not.supported.in.source", source.name);
- allowMethodReferences = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "method.references.not.supported.in.source", source.name);
}
}
void checkDefaultMethods() {
if (!allowDefaultMethods) {
- log.error(token.pos, "default.methods.not.supported.in.source", source.name);
- allowDefaultMethods = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "default.methods.not.supported.in.source", source.name);
}
}
void checkIntersectionTypesInCast() {
if (!allowIntersectionTypesInCast) {
- log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
- allowIntersectionTypesInCast = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
}
}
void checkStaticInterfaceMethods() {
if (!allowStaticInterfaceMethods) {
- log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
- allowStaticInterfaceMethods = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "static.intf.methods.not.supported.in.source", source.name);
}
}
void checkTypeAnnotations() {
if (!allowTypeAnnotations) {
- log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
- allowTypeAnnotations = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "type.annotations.not.supported.in.source", source.name);
}
}
void checkPrivateInterfaceMethods() {
if (!allowPrivateInterfaceMethods) {
- log.error(token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
- allowPrivateInterfaceMethods = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
}
}
protected void checkAnnotationsAfterTypeParams(int pos) {
if (!allowAnnotationsAfterTypeParams) {
- log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);
- allowAnnotationsAfterTypeParams = true;
+ log.error(DiagnosticFlag.SOURCE_LEVEL, pos, "annotations.after.type.params.not.supported.in.source", source.name);
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java Mon Aug 29 08:53:32 2016 -0700
@@ -32,6 +32,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -86,7 +87,7 @@
}
}
}
- } catch (IOException ex) {
+ } catch (IOException | ProviderNotFoundException ex) {
}
}
SUPPORTED_JAVA_PLATFORM_VERSIONS.add(targetNumericVersion(Target.DEFAULT));
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Aug 29 08:53:32 2016 -0700
@@ -672,6 +672,9 @@
compiler.err.cannot.create.array.with.diamond=\
cannot create array with ''<>''
+compiler.err.invalid.module.directive=\
+ module directive keyword or ''}'' expected
+
#
# limits. We don't give the limits in the diagnostic because we expect
# them to change, yet we want to use the same diagnostic. These are all
@@ -1664,6 +1667,10 @@
compiler.warn.unexpected.archive.file=\
Unexpected extension for archive file: {0}
+# 0: path
+compiler.err.no.zipfs.for.archive=\
+ No file system provider is available to handle this file: {0}
+
compiler.warn.div.zero=\
division by zero
@@ -1868,6 +1875,10 @@
compiler.misc.invalid.static.interface=\
static method found in version {0}.{1} classfile
+# 0: string (classfile major version), 1: string (classfile minor version)
+compiler.misc.anachronistic.module.info=\
+ module declaration found in version {0}.{1} classfile
+
# 0: name
compiler.misc.file.doesnt.contain.class=\
file does not contain class {0}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Mon Aug 29 08:53:32 2016 -0700
@@ -435,7 +435,10 @@
COMPRESSED,
/** Print multiple errors for same source locations.
*/
- MULTIPLE;
+ MULTIPLE,
+ /** Flag for not-supported-in-source-X errors.
+ */
+ SOURCE_LEVEL;
}
private final DiagnosticSource source;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Mon Aug 29 08:53:32 2016 -0700
@@ -428,6 +428,11 @@
*/
protected Set<Pair<JavaFileObject, Integer>> recorded = new HashSet<>();
+ /** A set of "not-supported-in-source-X" errors produced so far. This is used to only generate
+ * one such error per file.
+ */
+ protected Set<Pair<JavaFileObject, String>> recordedSourceLevelErrors = new HashSet<>();
+
public boolean hasDiagnosticListener() {
return diagListener != null;
}
@@ -507,6 +512,27 @@
return shouldReport;
}
+ /** Returns true if a diagnostics needs to be reported.
+ */
+ private boolean shouldReport(JCDiagnostic d) {
+ JavaFileObject file = d.getSource();
+
+ if (file == null)
+ return true;
+
+ if (!shouldReport(file, d.getIntPosition()))
+ return false;
+
+ if (!d.isFlagSet(DiagnosticFlag.SOURCE_LEVEL))
+ return true;
+
+ Pair<JavaFileObject, String> coords = new Pair<>(file, d.getCode());
+ boolean shouldReport = !recordedSourceLevelErrors.contains(coords);
+ if (shouldReport)
+ recordedSourceLevelErrors.add(coords);
+ return shouldReport;
+ }
+
/** Prompt user after an error.
*/
public void prompt() {
@@ -671,7 +697,7 @@
case ERROR:
if (nerrors < MaxErrors &&
(diagnostic.isFlagSet(DiagnosticFlag.MULTIPLE) ||
- shouldReport(diagnostic.getSource(), diagnostic.getIntPosition()))) {
+ shouldReport(diagnostic))) {
writeDiagnostic(diagnostic);
nerrors++;
}
--- a/langtools/src/jdk.compiler/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,10 @@
* questions.
*/
+/** Defines the implementation of the
+ * {@link javax.tools.ToolProvider#getSystemJavaCompiler system Java compiler}
+ * and its command line equivalent, <em>javac</em>, as well as <em>javah</em>.
+ */
module jdk.compiler {
requires public java.compiler;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java Mon Aug 29 08:53:32 2016 -0700
@@ -63,8 +63,7 @@
/**
* Initializes this doclet with the given locale and error reporter.
* This locale will be used by the reporter and the doclet components.
- * It is recommended to call this as early as possible, for a
- * uniform localized user experience,
+ *
* @param locale the locale to be used
* @param reporter the reporter to be used
*/
@@ -74,6 +73,7 @@
* Returns a name identifying the doclet. A name is a simple identifier
* without white spaces, as defined in <cite>The Java™ Language Specification</cite>,
* section 6.2 "Names and Identifiers".
+ *
* @return name of the Doclet
*/
public abstract String getName();
@@ -81,7 +81,7 @@
/**
* Returns all the supported options.
*
- * @return a Set containing all the supported options, an empty set if none.
+ * @return a set containing all the supported options, an empty set if none
*/
public Set<Option> getSupportedOptions();
@@ -90,7 +90,7 @@
* by this doclet.
*
* @return the language version supported by this doclet, usually
- * the latest version.
+ * the latest version
*/
public SourceVersion getSupportedSourceVersion();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java Mon Aug 29 08:53:32 2016 -0700
@@ -30,6 +30,8 @@
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
@@ -48,17 +50,34 @@
public interface DocletEnvironment {
/**
* Returns the <a href="package-summary.html#included">included</a>
- * classes, interfaces and enums in all packages.
+ * modules.
+ *
+ * @return a set of included module elements
+ */
+ Set<ModuleElement> getIncludedModuleElements();
+
+ /**
+ * Returns the <a href="package-summary.html#included">included</a>
+ * annotation types, classes, interfaces and enums in all packages.
*
- * @return a Set containing {@link javax.lang.model.element.TypeElement TypeElements}.
+ * @return a set of included type elements
*/
- Set<TypeElement> getIncludedClasses();
+ Set<TypeElement> getIncludedTypeElements();
+
+ /**
+ * Returns the <a href="package-summary.html#included">included</a>
+ * packages.
+ *
+ * @return a set of included package elements
+ */
+ Set<PackageElement> getIncludedPackageElements();
/**
* Returns an instance of the {@code DocTrees} utility class.
* This class provides methods to access {@code TreePath}s, {@code DocCommentTree}s
* and so on.
- * @return a utility class to operate on doc trees.
+ *
+ * @return a utility class to operate on doc trees
*/
DocTrees getDocTrees();
@@ -66,21 +85,23 @@
* Returns an instance of the {@code Elements} utility class.
* This class provides methods for operating on
* {@link javax.lang.model.element.Element elements}.
+ *
* @return a utility class to operate on elements
*/
Elements getElementUtils();
/**
- * Returns the selected elements that can be documented.
+ * Returns the <a href="package-summary.html#included">selected</a>
+ * elements that can be documented.
*
* @param elements those that need to be checked
- * @return elements selected, an empty list if none.
+ * @return elements selected, an empty list if none
*/
List<Element> getSelectedElements(List<? extends Element> elements);
/**
- * Returns the elements <a href="package-summary.html#included">specified</a>
- * on the command line, usually PackageElements and TypeElements.
+ * Returns the elements <a href="package-summary.html#specified">specified</a>
+ * on the command line, usually module elements, package elements and type elements.
* If {@code -subpackages} and {@code -exclude} options
* are used, return all the non-excluded packages.
*
@@ -92,6 +113,7 @@
* Returns an instance of the {@code Types} utility class.
* This class provides methods for operating on
* {@link javax.lang.model.type.TypeMirror type mirrors}.
+ *
* @return a utility class to operate on type mirrors
*/
Types getTypeUtils();
@@ -117,4 +139,18 @@
* @return the source version
*/
SourceVersion getSourceVersion();
+
+ /**
+ * Returns the required level of module documentation.
+ *
+ * @return the required level of module documentation
+ */
+ public ModuleMode getModuleMode();
+
+ enum ModuleMode {
+ /** Indicate API level documentation is required */
+ API,
+ /** Indicate Detailed documentation is required */
+ ALL
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -27,7 +27,7 @@
* The Doclet API provides an environment which, in conjunction with
* the Language Model API and Compiler Tree API, allows clients
* to inspect the source-level structures of programs and
- * libraries, including javadoc comments embedded in the source.
+ * libraries, including API comments embedded in the source.
*
* <p style="font-style: italic">
* <b>Note:</b> The declarations in this package supersede those
@@ -57,15 +57,58 @@
* <a name="terminology"></a>
* <h3>Terminology</h3>
*
+ * <a name="specified"></a>
+ * Module, package and source file names can be provided as parameters to the
+ * javadoc tool -- these are called the <em>specified</em> set containing
+ * module elements, package elements and type elements.
+ * <p>
+ * Javadoc <em>selection control</em> can be specified with
+ * {@code --show-members:value}, {@code --showtypes:value}, where value can be one of
+ * the following:
+ * <ul>
+ * <li> public -- considers only public elements
+ * <li> protected -- considers public and protected elements
+ * <li> package -- considers public, protected and package private elements
+ * <li> private -- considers all elements
+ * </ul>
+ *
+ * The {@code --show-package:value} where a value of "exported" or "all" can be used to
+ * consider only exported packages or all packages within a module.
+ * <p>
+ * The {@code --expand-requires:value}, expands the "requires" directives of a
+ * module declaration, to create a module set to considered for documentation
+ * as follows:
+ * <ul>
+ * <li> public -- follows and expands all "requires public" edges in the module graph
+ * <li> all -- follows and expands all "requires" edges in the module graph.
+ * By default, only the specified modules will be considered, without expansion
+ * of the module dependencies.
+ * </ul>
* <a name="included"></a>
- * When calling javadoc, one can pass in package names and source file names --
- * these are called the <em>specified</em> PackageElements and TypeElements.
- * Javadoc options are also passed in; the <em>access control</em> Javadoc options
- * ({@code -public}, {@code -protected}, {@code -package},
- * and {@code -private}) are used to filter program elements, producing a
- * result set, called the <em>included</em> set, or "selected" set.
+ * All of the above are used to select the elements, to produce the
+ * <em>included</em> or the <em>selected</em> set.
+ * <p>
+ * {@code --show-module-contents:value} can be used to specify the level at
+ * module declarations could be documented, a value of "api" indicates API
+ * level documentation, and "all" indicates detailed documentation.
* <p>
-
+ * <a name="legacy-interactions"></a>
+ * <h4>Interactions with older options.</h4>
+ *
+ * The new --show-* options provide a more detailed replacement for the older
+ * options -public, -protected, -package, -private. Alternatively, the older
+ * options can continue to be used as shorter forms for combinations of the
+ * new options, as described below:
+ <table style="font-family: monospace" border=1>
+ <caption>Short form options mapping</caption>
+ <tr><th>Older option<th colspan="5">Equivalent to these values with the new option
+ <tr><th><th>--show-members<th>--show-types<th>--show-packages<th>--show-module-contents
+ <tr><td>-public<td>public<td>public<td>exported<td>api
+ <tr><td>-protected<td>protected<td>protected<td>exported<td>api
+ <tr><td>-package<td>package<td>package<td>all<td>all
+ <tr><td>-private<td>private<td>private<td>all<td>all
+ </table>
+ * <p>
* <a name="qualified"></a>
* A <em>qualified</em> element name is one that has its package
* name prepended to it, such as {@code java.lang.String}. A non-qualified
@@ -96,14 +139,14 @@
* }
*
* @Override
- * public boolean run(RootDoc root) {
+ * public boolean run(DocletEnvironment docEnv) {
* // cache the DocTrees utility class to access DocComments
- * DocTrees docTrees = root.getDocTrees();
+ * DocTrees docTrees = docEnv.getDocTrees();
*
* // location of an element in the same directory as overview.html
* try {
* Element barElement = null;
- * for (Element e : root.getIncludedClasses()) {
+ * for (Element e : docEnv.getIncludedClasses()) {
* if (e.getSimpleName().toString().equals("FooBar")) {
* barElement = e;
* }
@@ -118,7 +161,7 @@
* System.err.println("No overview.html found.");
* }
*
- * for (TypeElement t : root.getIncludedClasses()) {
+ * for (TypeElement t : docEnv.getIncludedClasses()) {
* System.out.println(t.getKind() + ":" + t);
* for (Element e : t.getEnclosedElements()) {
* DocCommentTree docCommentTree = docTrees.getDocCommentTree(e);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -115,7 +115,7 @@
* Add the summary link for the member.
*
* @param context the id of the context where the link will be printed
- * @param te the classDoc that we should link to
+ * @param te the type element being linked to
* @param member the member being linked to
* @param tdSummary the content tree to which the link will be added
*/
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -32,6 +32,7 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.SimpleElementVisitor9;
@@ -183,6 +184,15 @@
new SimpleElementVisitor9<Void, Void>() {
@Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+ public Void visitModule(ModuleElement e, Void p) {
+ if (configuration.showModules) {
+ addDescription(e, dl, si);
+ configuration.moduleSearchIndex.add(si);
+ }
+ return null;
+ }
+
+ @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
public Void visitPackage(PackageElement e, Void p) {
addDescription(e, dl, si);
configuration.packageSearchIndex.add(si);
@@ -207,6 +217,27 @@
}
/**
+ * Add one line summary comment for the module.
+ *
+ * @param mdle the module to be documented
+ * @param dlTree the content tree to which the description will be added
+ */
+ protected void addDescription(ModuleElement mdle, Content dlTree, SearchIndexItem si) {
+ String moduleName = utils.getSimpleName(mdle);
+ Content link = getModuleLink(mdle, new StringContent(moduleName));
+ si.setLabel(moduleName);
+ si.setCategory(resources.getText("doclet.Modules"));
+ Content dt = HtmlTree.DT(link);
+ dt.addContent(" - ");
+ dt.addContent(contents.module_);
+ dt.addContent(" " + moduleName);
+ dlTree.addContent(dt);
+ Content dd = new HtmlTree(HtmlTag.DD);
+ addSummaryComment(mdle, dd);
+ dlTree.addContent(dd);
+ }
+
+ /**
* Add one line summary comment for the package.
*
* @param pkg the package to be documented
@@ -214,6 +245,9 @@
*/
protected void addDescription(PackageElement pkg, Content dlTree, SearchIndexItem si) {
Content link = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
+ if (configuration.showModules) {
+ si.setContainingModule(utils.getSimpleName(utils.containingModule(pkg)));
+ }
si.setLabel(utils.getPackageName(pkg));
si.setCategory(resources.getText("doclet.Packages"));
Content dt = HtmlTree.DT(link);
@@ -397,6 +431,10 @@
}
protected void createSearchIndexFiles() {
+ if (configuration.showModules) {
+ createSearchIndexFile(DocPaths.MODULE_SEARCH_INDEX_JSON, DocPaths.MODULE_SEARCH_INDEX_ZIP,
+ configuration.moduleSearchIndex);
+ }
createSearchIndexFile(DocPaths.PACKAGE_SEARCH_INDEX_JSON, DocPaths.PACKAGE_SEARCH_INDEX_ZIP,
configuration.packageSearchIndex);
createSearchIndexFile(DocPaths.TYPE_SEARCH_INDEX_JSON, DocPaths.TYPE_SEARCH_INDEX_ZIP,
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
import java.io.*;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
@@ -57,7 +58,7 @@
/**
* Modules to be documented.
*/
- protected Map<ModuleElement, Set<PackageElement>> modules;
+ protected SortedMap<ModuleElement, Set<PackageElement>> modules;
/**
* Constructor. Also initializes the modules variable.
@@ -142,7 +143,7 @@
*
* @param title the title of the window.
* @param includeScript boolean set true if windowtitle script is to be included
- * @param moduleName the name of the module being documented
+ * @param mdle the name of the module being documented
*/
protected void buildModulePackagesIndexFile(String title,
boolean includeScript, ModuleElement mdle) throws IOException {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesFrameWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesFrameWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,7 +25,7 @@
package jdk.javadoc.internal.doclets.formats.html;
-import java.io.*;
+import java.io.IOException;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
@@ -89,25 +89,32 @@
* "allclasses-frame.html" file. Generate the file in the current or the
* destination directory.
*
- * @param indexbuilder IndexBuilder object for all classes index.
+ * @param indexBuilder IndexBuilder object for all classes index.
* @throws DocletAbortException
*/
public static void generate(ConfigurationImpl configuration,
- IndexBuilder indexbuilder) {
- AllClassesFrameWriter allclassgen;
- DocPath filename = DocPaths.ALLCLASSES_FRAME;
+ IndexBuilder indexBuilder) {
+ if (configuration.frames) {
+ generate(configuration, indexBuilder, DocPaths.ALLCLASSES_FRAME, true);
+ generate(configuration, indexBuilder, DocPaths.ALLCLASSES_NOFRAME, false);
+ } else {
+ generate(configuration, indexBuilder, DocPaths.ALLCLASSES, false);
+ }
+ }
+
+ private static void generate(ConfigurationImpl configuration, IndexBuilder indexBuilder,
+ DocPath fileName, boolean wantFrames) {
try {
+ AllClassesFrameWriter allclassgen = new AllClassesFrameWriter(configuration,
+ fileName, indexBuilder);
+ allclassgen.buildAllClassesFile(wantFrames);
allclassgen = new AllClassesFrameWriter(configuration,
- filename, indexbuilder);
- allclassgen.buildAllClassesFile(true);
- filename = DocPaths.ALLCLASSES_NOFRAME;
- allclassgen = new AllClassesFrameWriter(configuration,
- filename, indexbuilder);
+ fileName, indexBuilder);
allclassgen.buildAllClassesFile(false);
} catch (IOException exc) {
Messages messages = configuration.getMessages();
messages.error("doclet.exception_encountered",
- exc.toString(), filename);
+ exc.toString(), fileName);
throw new DocletAbortException(exc);
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -105,7 +105,7 @@
/**
* {@inheritDoc}
*/
- public void addAnnotationDetailsTreeHeader(TypeElement classDoc,
+ public void addAnnotationDetailsTreeHeader(TypeElement te,
Content memberDetailsTree) {
if (!writer.printedAnnotationHeading) {
memberDetailsTree.addContent(writer.getMarkerAnchor(
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -179,7 +179,7 @@
*/
public static void generate(ConfigurationImpl configuration, ClassTree classtree) {
ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
- for (TypeElement aClass : configuration.docEnv.getIncludedClasses()) {
+ for (TypeElement aClass : configuration.docEnv.getIncludedTypeElements()) {
// If -nodeprecated option is set and the containing package is marked
// as deprecated, do not generate the class-use page. We will still generate
// the class-use page if the class is marked as deprecated but the containing
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -209,7 +209,7 @@
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.header);
ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement);
- if (mdle != null && !mdle.isUnnamed()) {
+ if (configuration.showModules) {
Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInClass, contents.moduleLabel);
Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel);
moduleNameDiv.addContent(Contents.SPACE);
@@ -651,11 +651,11 @@
if (type instanceof TypeElement) {
Content link = getLink(
new LinkInfoImpl(configuration, context, (TypeElement)(type)));
- dd.addContent(link);
+ dd.addContent(HtmlTree.CODE(link));
} else {
Content link = getLink(
new LinkInfoImpl(configuration, context, ((TypeMirror)type)));
- dd.addContent(link);
+ dd.addContent(HtmlTree.CODE(link));
}
}
return dd;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,7 +25,6 @@
package jdk.javadoc.internal.doclets.formats.html;
-import java.io.IOException;
import java.net.*;
import java.util.*;
@@ -34,14 +33,10 @@
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
-import javax.tools.JavaFileManager.Location;
import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
import com.sun.source.util.DocTreePath;
import com.sun.tools.doclint.DocLint;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
@@ -198,6 +193,12 @@
public boolean createoverview = false;
/**
+ * Specifies whether or not frames should be generated.
+ * Defaults to true; can be set by --frames; can be set to false by --no-frames; last one wins.
+ */
+ public boolean frames = true;
+
+ /**
* This is the HTML version of the generated pages. HTML 4.01 is the default output version.
*/
public HtmlVersion htmlVersion = HtmlVersion.HTML4;
@@ -222,6 +223,8 @@
protected List<SearchIndexItem> memberSearchIndex = new ArrayList<>();
+ protected List<SearchIndexItem> moduleSearchIndex = new ArrayList<>();
+
protected List<SearchIndexItem> packageSearchIndex = new ArrayList<>();
protected List<SearchIndexItem> tagSearchIndex = new ArrayList<>();
@@ -377,7 +380,7 @@
if (!docEnv.getSpecifiedElements().isEmpty()) {
Map<String, PackageElement> map = new HashMap<>();
PackageElement pkg;
- List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
+ List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
for (TypeElement aClass : classes) {
pkg = utils.containingPackage(aClass);
if (!map.containsKey(utils.getPackageName(pkg))) {
@@ -414,18 +417,20 @@
* package to document. It will be a class page(first in the sorted order),
* if only classes are provided on the command line.
*
- * @param root Root of the program structure.
+ * @param docEnv the doclet environment
*/
- protected void setTopFile(DocletEnvironment root) {
- if (!checkForDeprecation(root)) {
+ protected void setTopFile(DocletEnvironment docEnv) {
+ if (!checkForDeprecation(docEnv)) {
return;
}
if (createoverview) {
- topFile = DocPaths.OVERVIEW_SUMMARY;
+ topFile = DocPaths.overviewSummary(frames);
} else {
- if (packages.size() == 1 && packages.first().isUnnamed()) {
- if (!root.getIncludedClasses().isEmpty()) {
- List<TypeElement> classes = new ArrayList<>(root.getIncludedClasses());
+ if (showModules) {
+ topFile = DocPath.empty.resolve(DocPaths.moduleSummary(modules.first()));
+ } else if (packages.size() == 1 && packages.first().isUnnamed()) {
+ List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
+ if (!classes.isEmpty()) {
TypeElement te = getValidClass(classes);
topFile = DocPath.forClass(utils, te);
}
@@ -448,7 +453,7 @@
}
protected boolean checkForDeprecation(DocletEnvironment docEnv) {
- for (TypeElement te : docEnv.getIncludedClasses()) {
+ for (TypeElement te : docEnv.getIncludedTypeElements()) {
if (isGeneratedDoc(te)) {
return true;
}
@@ -573,21 +578,6 @@
return contents.getContent(key, o0, o1, o2);
}
-
- @Override
- public Location getLocationForPackage(PackageElement pd) {
- JavaFileManager fm = getFileManager();
- if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH) && (pd instanceof PackageSymbol)) {
- try {
- ModuleSymbol msym = ((PackageSymbol) pd).modle;
- return fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, msym.name.toString());
- } catch (IOException e) {
- throw new DocletAbortException(e);
- }
- }
- return StandardLocation.SOURCE_PATH;
- }
-
protected void buildSearchTagIndex() {
for (SearchIndexItem sii : tagSearchIndex) {
String tagLabel = sii.getLabel();
@@ -719,7 +709,7 @@
return true;
}
},
- new Hidden(this, "-overview", 1) {
+ new Option(this, "-overview", 1) {
@Override
public boolean process(String opt, ListIterator<String> args) {
optionsProcessed.add(this);
@@ -727,6 +717,22 @@
return true;
}
},
+ new Option(this, "--frames") {
+ @Override
+ public boolean process(String opt, ListIterator<String> args) {
+ optionsProcessed.add(this);
+ frames = true;
+ return true;
+ }
+ },
+ new Option(this, "--no-frames") {
+ @Override
+ public boolean process(String opt, ListIterator<String> args) {
+ optionsProcessed.add(this);
+ frames = false;
+ return true;
+ }
+ },
new Hidden(this, "-packagesheader", 1) {
@Override
public boolean process(String opt, ListIterator<String> args) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java Mon Aug 29 08:53:32 2016 -0700
@@ -104,6 +104,7 @@
public final Content methodSummary;
public final Content methods;
public final Content moduleLabel;
+ public final Content module_;
public final Content moduleSubNavLabel;
public final Content modulesLabel;
public final Content navAnnotationTypeMember;
@@ -216,6 +217,7 @@
methodSummary = getContent("doclet.Method_Summary");
methods = getContent("doclet.Methods");
moduleLabel = getContent("doclet.Module");
+ module_ = getContent("doclet.module");
moduleSubNavLabel = getContent("doclet.Module_Sub_Nav");
modulesLabel = getContent("doclet.Modules");
navAnnotationTypeMember = getContent("doclet.navAnnotationTypeMember");
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -141,7 +141,7 @@
? HtmlTree.SECTION(overviewHeading)
: HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
Content line3 = contents.getContent("doclet.Help_line_3",
- getHyperLink(DocPaths.OVERVIEW_SUMMARY,
+ getHyperLink(DocPaths.overviewSummary(configuration.frames),
configuration.getText("doclet.Overview")));
Content overviewPara = HtmlTree.P(line3);
htmlTree.addContent(overviewPara);
@@ -362,26 +362,31 @@
} else {
ul.addContent(htmlTree);
}
- Content frameHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
- contents.getContent("doclet.Help_line_25"));
- htmlTree = (configuration.allowTag(HtmlTag.SECTION))
- ? HtmlTree.SECTION(frameHead)
- : HtmlTree.LI(HtmlStyle.blockList, frameHead);
- Content line26 = contents.getContent("doclet.Help_line_26");
- Content framePara = HtmlTree.P(line26);
- htmlTree.addContent(framePara);
+
+ if (configuration.frames) {
+ Content frameHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
+ contents.getContent("doclet.Help_line_25"));
+ htmlTree = (configuration.allowTag(HtmlTag.SECTION))
+ ? HtmlTree.SECTION(frameHead)
+ : HtmlTree.LI(HtmlStyle.blockList, frameHead);
+ Content line26 = contents.getContent("doclet.Help_line_26");
+ Content framePara = HtmlTree.P(line26);
+ htmlTree.addContent(framePara);
+ }
+
if (configuration.allowTag(HtmlTag.SECTION)) {
ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
} else {
ul.addContent(htmlTree);
}
+
Content allclassesHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
contents.allClassesLabel);
htmlTree = (configuration.allowTag(HtmlTag.SECTION))
? HtmlTree.SECTION(allclassesHead)
: HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
Content line27 = contents.getContent("doclet.Help_line_27",
- getHyperLink(DocPaths.ALLCLASSES_NOFRAME,
+ getHyperLink(DocPaths.AllClasses(configuration.frames),
resources.getText("doclet.All_Classes")));
Content allclassesPara = HtmlTree.P(line27);
htmlTree.addContent(allclassesPara);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java Mon Aug 29 08:53:32 2016 -0700
@@ -106,7 +106,7 @@
*
* For new format.
*
- * @see jdk.doclet.RootDoc
+ * @see jdk.doclet.DocletEnvironment
*/
@Override // defined by AbstractDoclet
protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree)
@@ -149,7 +149,9 @@
AllClassesFrameWriter.generate(configuration,
new IndexBuilder(configuration, nodeprecated, true));
- FrameOutputWriter.generate(configuration);
+ if (configuration.frames) {
+ FrameOutputWriter.generate(configuration);
+ }
if (configuration.createoverview) {
if (configuration.showModules) {
@@ -158,6 +160,11 @@
PackageIndexWriter.generate(configuration);
}
}
+
+ if (!configuration.frames && !configuration.createoverview) {
+ IndexRedirectWriter.generate(configuration);
+ }
+
if (configuration.helpfile.length() == 0 &&
!configuration.nohelp) {
HelpWriter.generate(configuration);
@@ -270,13 +277,17 @@
@Override // defined by AbstractDoclet
protected void generateModuleFiles() throws Exception {
if (configuration.showModules) {
- ModuleIndexFrameWriter.generate(configuration);
+ if (configuration.frames) {
+ ModuleIndexFrameWriter.generate(configuration);
+ }
ModuleElement prevModule = null, nextModule;
List<ModuleElement> mdles = new ArrayList<>(configuration.modulePackages.keySet());
int i = 0;
for (ModuleElement mdle : mdles) {
- ModulePackageIndexFrameWriter.generate(configuration, mdle);
- ModuleFrameWriter.generate(configuration, mdle);
+ if (configuration.frames) {
+ ModulePackageIndexFrameWriter.generate(configuration, mdle);
+ ModuleFrameWriter.generate(configuration, mdle);
+ }
nextModule = (i + 1 < mdles.size()) ? mdles.get(i + 1) : null;
AbstractBuilder moduleSummaryBuilder =
configuration.getBuilderFactory().getModuleSummaryBuilder(
@@ -304,7 +315,7 @@
@Override // defined by AbstractDoclet
protected void generatePackageFiles(ClassTree classtree) throws Exception {
Set<PackageElement> packages = configuration.packages;
- if (packages.size() > 1) {
+ if (packages.size() > 1 && configuration.frames) {
PackageIndexFrameWriter.generate(configuration);
}
List<PackageElement> pList = new ArrayList<>(packages);
@@ -315,7 +326,9 @@
// and package-tree.html pages for that package.
PackageElement pkg = pList.get(i);
if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) {
- PackageFrameWriter.generate(configuration, pkg);
+ if (configuration.frames) {
+ PackageFrameWriter.generate(configuration, pkg);
+ }
int nexti = i + 1;
PackageElement next = null;
if (nexti < pList.size()) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -580,10 +580,12 @@
if (configuration.createoverview) {
navList.addContent(getNavLinkContents());
}
- if (configuration.modules.size() == 1) {
- navList.addContent(getNavLinkModule(configuration.modules.first()));
- } else if (!configuration.modules.isEmpty()) {
- navList.addContent(getNavLinkModule());
+ if (configuration.showModules) {
+ if (configuration.modules.size() == 1) {
+ navList.addContent(getNavLinkModule(configuration.modules.first()));
+ } else if (!configuration.modules.isEmpty()) {
+ navList.addContent(getNavLinkModule());
+ }
}
if (configuration.packages.size() == 1) {
navList.addContent(getNavLinkPackage(configuration.packages.first()));
@@ -615,12 +617,13 @@
} else {
tree.addContent(navDiv);
}
- Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious());
- ulNav.addContent(getNavLinkNext());
+ Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious(), getNavLinkNext());
Content subDiv = HtmlTree.DIV(HtmlStyle.subNav, ulNav);
- Content ulFrames = HtmlTree.UL(HtmlStyle.navList, getNavShowLists());
- ulFrames.addContent(getNavHideLists(filename));
- subDiv.addContent(ulFrames);
+ if (configuration.frames) {
+ Content ulFrames = HtmlTree.UL(HtmlStyle.navList,
+ getNavShowLists(), getNavHideLists(filename));
+ subDiv.addContent(ulFrames);
+ }
HtmlTree ulAllClasses = HtmlTree.UL(HtmlStyle.navList, getNavLinkClassIndex());
ulAllClasses.addAttr(HtmlAttr.ID, allClassesId);
subDiv.addContent(ulAllClasses);
@@ -688,7 +691,7 @@
* @return a content tree for the link
*/
protected Content getNavLinkContents() {
- Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_SUMMARY),
+ Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
contents.overviewLabel, "", "");
Content li = HtmlTree.LI(linkContent);
return li;
@@ -824,8 +827,8 @@
* @return a content tree for the link
*/
protected Content getNavLinkTree() {
- List<PackageElement> packages = new ArrayList<>(utils.getSpecifiedPackages());
- DocPath docPath = packages.size() == 1 && utils.getSpecifiedClasses().isEmpty()
+ List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackages());
+ DocPath docPath = packages.size() == 1 && configuration.getSpecifiedClasses().isEmpty()
? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));
@@ -875,7 +878,7 @@
*/
protected Content getNavLinkClassIndex() {
Content allClassesContent = getHyperLink(pathToRoot.resolve(
- DocPaths.ALLCLASSES_NOFRAME),
+ DocPaths.AllClasses(configuration.frames)),
contents.allClassesLabel, "", "");
Content li = HtmlTree.LI(allClassesContent);
return li;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.formats.html;
+
+import java.io.IOException;
+
+import jdk.javadoc.internal.doclets.formats.html.markup.Comment;
+import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
+import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
+import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.Messages;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
+import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException;
+
+import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocWriter.CONTENT_TYPE;
+
+/**
+ * Writes an index.html file that tries to redirect to an alternate page.
+ * The redirect uses JavaSCript, if enabled, falling back on
+ * {@code <meta http-eqiv=refresh content="0,<uri>">}.
+ * If neither are supported/enabled in a browser, the page displays the
+ * standard "JavaScipt not enabled" message, and a link to the alternate page.
+ */
+public class IndexRedirectWriter extends HtmlDocletWriter {
+
+ public static void generate(ConfigurationImpl configuration) {
+ IndexRedirectWriter indexRedirect;
+ DocPath filename = DocPath.empty;
+ try {
+ filename = DocPaths.INDEX;
+ indexRedirect = new IndexRedirectWriter(configuration, filename);
+ indexRedirect.generateIndexFile();
+ } catch (IOException exc) {
+ Messages messages = configuration.getMessages();
+ messages.error(
+ "doclet.exception_encountered",
+ exc.toString(), filename);
+ throw new DocletAbortException(exc);
+ }
+ }
+
+ IndexRedirectWriter(ConfigurationImpl configuration, DocPath filename)
+ throws IOException {
+ super(configuration, filename);
+ }
+
+ void generateIndexFile() throws IOException {
+ Content htmlDocType = configuration.isOutputHtml5()
+ ? DocType.HTML5
+ : DocType.TRANSITIONAL;
+ Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
+ Content head = new HtmlTree(HtmlTag.HEAD);
+ head.addContent(getGeneratedBy(!configuration.notimestamp));
+
+ String title = (configuration.windowtitle.length() > 0)
+ ? configuration.windowtitle
+ : configuration.getText("doclet.Generated_Docs_Untitled");
+
+ Content windowTitle = HtmlTree.TITLE(new StringContent(title));
+ head.addContent(windowTitle);
+ Content metaContentType = HtmlTree.META("Content", CONTENT_TYPE,
+ (configuration.charset.length() > 0) ?
+ configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+ head.addContent(metaContentType);
+
+ String topFilePath = configuration.topFile.getPath();
+ String javaScriptRefresh = "window.location.replace('" + topFilePath + "')";
+ HtmlTree scriptTree = HtmlTree.SCRIPT();
+ scriptTree.addContent(javaScriptRefresh);
+ head.addContent(scriptTree);
+ HtmlTree metaRefresh = new HtmlTree(HtmlTag.META);
+ metaRefresh.addAttr(HtmlAttr.HTTP_EQUIV, "Refresh");
+ metaRefresh.addAttr(HtmlAttr.CONTENT, "0;" + topFilePath);
+ if (configuration.isOutputHtml5()) {
+ head.addContent(HtmlTree.NOSCRIPT(metaRefresh));
+ } else {
+ head.addContent(metaRefresh);
+ }
+
+ head.addContent(getStyleSheetProperties(configuration));
+
+ ContentBuilder bodyContent = new ContentBuilder();
+ bodyContent.addContent(HtmlTree.NOSCRIPT(
+ HtmlTree.P(configuration.getContent("doclet.No_Script_Message"))));
+
+ bodyContent.addContent(HtmlTree.P(HtmlTree.A(topFilePath, new StringContent(topFilePath))));
+
+ Content body = new HtmlTree(HtmlTag.BODY);
+ if (configuration.allowTag(HtmlTag.MAIN)) {
+ HtmlTree main = HtmlTree.MAIN(bodyContent);
+ body.addContent(main);
+ } else {
+ body.addContent(bodyContent);
+ }
+
+ Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
+ head, body);
+ Content htmlDocument = new HtmlDocument(htmlDocType,
+ htmlComment, htmlTree);
+ write(htmlDocument);
+
+ }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -80,9 +80,9 @@
throws IOException {
super(configuration, DocPaths.moduleTypeFrame(moduleElement));
this.mdle = moduleElement;
- if (utils.getSpecifiedPackages().isEmpty()) {
+ if (configuration.getSpecifiedPackages().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+ documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -88,7 +88,7 @@
*/
public static void generate(ConfigurationImpl configuration) {
ModuleIndexWriter mdlgen;
- DocPath filename = DocPaths.OVERVIEW_SUMMARY;
+ DocPath filename = DocPaths.overviewSummary(configuration.frames);
try {
mdlgen = new ModuleIndexWriter(configuration, filename);
mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", true);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -84,9 +84,9 @@
public PackageFrameWriter(ConfigurationImpl configuration, PackageElement packageElement) {
super(configuration, DocPath.forPackage(packageElement).resolve(DocPaths.PACKAGE_FRAME));
this.packageElement = packageElement;
- if (utils.getSpecifiedPackages().isEmpty()) {
+ if (configuration.getSpecifiedPackages().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+ documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
}
}
@@ -136,7 +136,7 @@
*/
protected void addClassListing(HtmlTree contentTree) {
Configuration config = configuration;
- if (utils.isIncluded(packageElement)) {
+ if (utils.isSpecified(packageElement)) {
addClassKindListing(utils.getInterfaces(packageElement),
contents.interfaces, contentTree);
addClassKindListing(utils.getOrdinaryClasses(packageElement),
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -101,7 +101,7 @@
*/
public static void generate(ConfigurationImpl configuration) {
PackageIndexWriter packgen;
- DocPath filename = DocPaths.OVERVIEW_SUMMARY;
+ DocPath filename = DocPaths.overviewSummary(configuration.frames);
try {
packgen = new PackageIndexWriter(configuration, filename);
packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", true);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -125,7 +125,7 @@
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.header);
ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement);
- if (mdle != null && !mdle.isUnnamed()) {
+ if (configuration.showModules) {
Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInClass, contents.moduleLabel);
Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel);
moduleNameDiv.addContent(Contents.SPACE);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java Mon Aug 29 08:53:32 2016 -0700
@@ -38,6 +38,7 @@
private String label = "";
private String url = "";
private String category = "";
+ private String containingModule = "";
private String containingPackage = "";
private String containingClass = "";
private String holder = "";
@@ -59,6 +60,10 @@
return url;
}
+ public void setContainingModule(String m) {
+ containingModule = m;
+ }
+
public void setContainingPackage(String p) {
containingPackage = p;
}
@@ -89,10 +94,17 @@
public String toString() {
StringBuilder item = new StringBuilder("");
- if (category.equals("Packages")) {
+ if (category.equals("Modules")) {
item.append("{")
.append("\"l\":\"").append(label).append("\"")
.append("}");
+ } else if (category.equals("Packages")) {
+ item.append("{");
+ if (!containingModule.isEmpty()) {
+ item.append("\"m\":\"").append(containingModule).append("\",");
+ }
+ item.append("\"l\":\"").append(label).append("\"")
+ .append("}");
} else if (category.equals("Types")) {
item.append("{")
.append("\"p\":\"").append(containingPackage).append("\",")
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -70,7 +70,7 @@
public SerializedFormWriterImpl(ConfigurationImpl configuration)
throws IOException {
super(configuration, DocPaths.SERIALIZED_FORM);
- visibleClasses = configuration.docEnv.getIncludedClasses();
+ visibleClasses = configuration.docEnv.getIncludedTypeElements();
}
/**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Mon Aug 29 08:53:32 2016 -0700
@@ -112,13 +112,13 @@
if (docEnv == null || outputdir == null) {
return;
}
- for (PackageElement pkg : utils.getSpecifiedPackages()) {
+ for (PackageElement pkg : configuration.getSpecifiedPackages()) {
// If -nodeprecated option is set and the package is marked as deprecated,
// do not convert the package files to HTML.
if (!(configuration.nodeprecated && utils.isDeprecated(pkg)))
convertPackage(pkg, outputdir);
}
- for (TypeElement te : utils.getSpecifiedClasses()) {
+ for (TypeElement te : configuration.getSpecifiedClasses()) {
// If -nodeprecated option is set and the class is marked as deprecated
// or the containing package is deprecated, do not convert the
// package files to HTML.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
import java.util.List;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
@@ -37,7 +38,6 @@
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.IndexTree;
import com.sun.tools.javac.util.DefinedBy;
-
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;
@@ -114,6 +114,13 @@
si.setDescription(desc);
new SimpleElementVisitor9<Void, Void>() {
@Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+ public Void visitModule(ModuleElement e, Void p) {
+ si.setUrl(DocPaths.moduleSummary(e).getPath() + "#" + anchorName);
+ si.setHolder(utils.getSimpleName(element));
+ return null;
+ }
+
+ @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
public Void visitPackage(PackageElement e, Void p) {
si.setUrl(DocPath.forPackage(e).getPath()
+ "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java Mon Aug 29 08:53:32 2016 -0700
@@ -833,13 +833,18 @@
* Generates a UL tag with the style class attribute and some content.
*
* @param styleClass style for the tag
- * @param body content for the tag
+ * @param first initial content to be added
+ * @param more a series of additional content nodes to be added
* @return an HtmlTree object for the UL tag
*/
- public static HtmlTree UL(HtmlStyle styleClass, Content body) {
- HtmlTree htmltree = new HtmlTree(HtmlTag.UL, nullCheck(body));
- htmltree.addStyle(nullCheck(styleClass));
- return htmltree;
+ public static HtmlTree UL(HtmlStyle styleClass, Content first, Content... more) {
+ HtmlTree htmlTree = new HtmlTree(HtmlTag.UL);
+ htmlTree.addContent(nullCheck(first));
+ for (Content c : more) {
+ htmlTree.addContent(nullCheck(c));
+ }
+ htmlTree.addStyle(nullCheck(styleClass));
+ return htmlTree;
}
/**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
var noResult = {l: "No results found"};
var category = "category";
+var catModules = "Modules";
var catPackages = "Packages";
var catTypes = "Types";
var catMembers = "Members";
@@ -115,8 +116,12 @@
var regexp = new RegExp($.ui.autocomplete.escapeRegex(result), "i");
highlight = "<span class=\"resultHighlight\">$&</span>";
var label = "";
- if (item.category === catPackages) {
+ if (item.category === catModules) {
label = item.l.replace(regexp, highlight);
+ } else if (item.category === catPackages) {
+ label = (item.m)
+ ? (item.m + "/" + item.l).replace(regexp, highlight)
+ : item.l.replace(regexp, highlight);
} else if (item.category === catTypes) {
label += (item.p + "." + item.l).replace(regexp, highlight);
} else if (item.category === catMembers) {
@@ -152,24 +157,43 @@
delay: 100,
source: function(request, response) {
var result = new Array();
+ var presult = new Array();
var tresult = new Array();
var mresult = new Array();
var tgresult = new Array();
var displayCount = 0;
var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
var secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
- if (packageSearchIndex) {
- var pCount = 0;
- $.each(packageSearchIndex, function(index, item) {
- item[category] = catPackages;
+ if (moduleSearchIndex) {
+ var mdleCount = 0;
+ $.each(moduleSearchIndex, function(index, item) {
+ item[category] = catModules;
if (exactMatcher.test(item.l)) {
result.unshift(item);
- pCount++;
+ mdleCount++;
} else if (secondaryMatcher.test(item.l)) {
result.push(item);
}
});
- displayCount = pCount;
+ displayCount = mdleCount;
+ }
+ if (packageSearchIndex) {
+ var pCount = 0;
+ var pkg = "";
+ $.each(packageSearchIndex, function(index, item) {
+ item[category] = catPackages;
+ pkg = (item.m)
+ ? (item.m + "/" + item.l)
+ : item.l;
+ if (exactMatcher.test(item.l)) {
+ presult.unshift(item);
+ pCount++;
+ } else if (secondaryMatcher.test(pkg)) {
+ presult.push(item);
+ }
+ });
+ result = result.concat(presult);
+ displayCount = (pCount > displayCount) ? pCount : displayCount;
}
if (typeSearchIndex) {
var tCount = 0;
@@ -215,7 +239,7 @@
}
displayCount = (displayCount > 500) ? displayCount : 500;
var counter = function() {
- var count = {Packages: 0, Types: 0, Members: 0, SearchTags: 0};
+ var count = {Modules: 0, Packages: 0, Types: 0, Members: 0, SearchTags: 0};
var f = function(item) {
count[item.category] += 1;
return (count[item.category] <= displayCount);
@@ -238,7 +262,9 @@
select: function(event, ui) {
if (ui.item.l !== noResult.l) {
var url = "";
- if (ui.item.category === catPackages) {
+ if (ui.item.category === catModules) {
+ url = "/" + ui.item.l + "-summary.html";
+ } else if (ui.item.category === catPackages) {
url = ui.item.l.replace(/\./g, '/') + "/package-summary.html";
} else if (ui.item.category === catTypes) {
if (ui.item.p === "<Unnamed>") {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Mon Aug 29 08:53:32 2016 -0700
@@ -62,6 +62,7 @@
doclet.Static_method_in=Static method in {0}
doclet.Search_tag_in=Search tag in {0}
doclet.Method_in=Method in {0}
+doclet.module=module
doclet.package=package
doclet.MalformedURL=Malformed URL: {0}
doclet.File_error=Error reading file: {0}
@@ -204,6 +205,10 @@
doclet.usage.splitindex.description=Split index into one file per letter
+doclet.usage.overview.parameters=<file>
+doclet.usage.overview.description=Read overview documentation from HTML file
+
+
doclet.usage.windowtitle.parameters=<text>
doclet.usage.windowtitle.description=Browser window title for the documentation
@@ -299,6 +304,10 @@
doclet.usage.docencoding.parameters=<name>
doclet.usage.docencoding.description=Specify the character encoding for the output
+doclet.usage.frames.description=Enable the use of frames in the generated output (default)
+
+doclet.usage.no-frames.description=Disable the use of frames in the generated output
+
doclet.xusage.xdocrootparent.parameters=<url>
doclet.xusage.xdocrootparent.description=Replaces all @docRoot followed by /..\n\
\ in doc comments with <url>
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Mon Aug 29 08:53:32 2016 -0700
@@ -90,13 +90,13 @@
/**
* The method that starts the execution of the doclet.
*
- * @param root the {@link DocletEnvironment} that points to the source to document.
+ * @param docEnv the {@link DocletEnvironment}.
* @return true if the doclet executed without error. False otherwise.
*/
@Override
- public boolean run(DocletEnvironment root) {
+ public boolean run(DocletEnvironment docEnv) {
configuration = configuration();
- configuration.docEnv = root;
+ configuration.docEnv = docEnv;
configuration.cmtUtils = new CommentUtils(configuration);
configuration.utils = new Utils(configuration);
utils = configuration.utils;
@@ -108,7 +108,7 @@
}
try {
- startGeneration(root);
+ startGeneration(docEnv);
} catch (Configuration.Fault f) {
configuration.reporter.print(ERROR, f.getMessage());
return false;
@@ -153,8 +153,8 @@
*
* @see jdk.doclet.DocletEnvironment
*/
- private void startGeneration(DocletEnvironment root) throws Configuration.Fault, Exception {
- if (root.getIncludedClasses().isEmpty()) {
+ private void startGeneration(DocletEnvironment docEnv) throws Configuration.Fault, Exception {
+ if (docEnv.getIncludedTypeElements().isEmpty()) {
messages.error("doclet.No_Public_Classes_To_Document");
return;
}
@@ -165,24 +165,24 @@
configuration.getDocletSpecificBuildDate());
ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
- generateClassFiles(root, classtree);
+ generateClassFiles(docEnv, classtree);
configuration.utils.copyDocFiles(DocPaths.DOC_FILES);
PackageListWriter.generate(configuration);
generatePackageFiles(classtree);
generateModuleFiles();
- generateOtherFiles(root, classtree);
+ generateOtherFiles(docEnv, classtree);
configuration.tagletManager.printReport();
}
/**
* Generate additional documentation that is added to the API documentation.
*
- * @param root the DocletEnvironment of source to document.
+ * @param docEnv the DocletEnvironment.
* @param classtree the data structure representing the class tree.
*/
- protected void generateOtherFiles(DocletEnvironment root, ClassTree classtree) throws Exception {
+ protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree) throws Exception {
BuilderFactory builderFactory = configuration.getBuilderFactory();
AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuilder();
constantsSummaryBuilder.build();
@@ -213,13 +213,16 @@
/**
* Iterate through all classes and construct documentation for them.
*
- * @param root the DocletEnvironment of source to document.
+ * @param docEnv the DocletEnvironment.
* @param classtree the data structure representing the class tree.
*/
- protected void generateClassFiles(DocletEnvironment root, ClassTree classtree) {
+ protected void generateClassFiles(DocletEnvironment docEnv, ClassTree classtree) {
generateClassFiles(classtree);
SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(utils.getSpecifiedPackages());
+ packages.addAll(configuration.getSpecifiedPackages());
+ configuration.modulePackages.values().stream().forEach(pset -> {
+ packages.addAll(pset);
+ });
packages.stream().forEach((pkg) -> {
generateClassFiles(utils.getAllClasses(pkg), classtree);
});
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Mon Aug 29 08:53:32 2016 -0700
@@ -32,8 +32,8 @@
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import com.sun.source.util.DocTreePath;
@@ -164,17 +164,17 @@
public final MetaKeywords metakeywords;
/**
- * The list of doc-file subdirectories to exclude
+ * The set of doc-file subdirectories to exclude
*/
protected Set<String> excludedDocFileDirs;
/**
- * The list of qualifiers to exclude
+ * The set of qualifiers to exclude
*/
protected Set<String> excludedQualifiers;
/**
- * The Root of the generated Program Structure from the Doclet API.
+ * The doclet environment.
*/
public DocletEnvironment docEnv;
@@ -314,14 +314,13 @@
public abstract boolean finishOptionSettings();
public CommentUtils cmtUtils;
- public SortedSet<ModuleElement> modules;
/**
* A sorted set of packages specified on the command-line merged with a
* collection of packages that contain the classes specified on the
* command-line.
*/
- public SortedSet<PackageElement> packages;
+ public SortedSet<PackageElement> packages = null;
protected final List<Doclet.Option> optionsProcessed;
@@ -335,9 +334,14 @@
public DocFileFactory docFileFactory;
/**
- * A sorted set of modules containing the packages.
+ * A sorted map, giving the (specified|included|other) packages for each module.
*/
- public Map<ModuleElement, Set<PackageElement>> modulePackages;
+ public SortedMap<ModuleElement, Set<PackageElement>> modulePackages;
+
+ /**
+ * The list of known modules, that should be documented.
+ */
+ public SortedSet<ModuleElement> modules;
protected static final String sharedResourceBundleName =
"jdk.javadoc.internal.doclets.toolkit.resources.doclets";
@@ -372,25 +376,39 @@
private void initModules() {
// Build the modules structure used by the doclet
+ modules = new TreeSet<>(utils.makeModuleComparator());
+ modules.addAll(getSpecifiedModules());
+
modulePackages = new TreeMap<>(utils.makeModuleComparator());
for (PackageElement p: packages) {
ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
if (mdle != null && !mdle.isUnnamed()) {
- Set<PackageElement> s = modulePackages.get(mdle);
- if (s == null)
- modulePackages.put(mdle, s = new TreeSet<>(utils.makePackageComparator()));
+ Set<PackageElement> s = modulePackages
+ .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
s.add(p);
}
}
- modules = new TreeSet<>(utils.makeModuleComparator());
+
+ for (PackageElement p: docEnv.getIncludedPackageElements()) {
+ ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
+ if (mdle != null && !mdle.isUnnamed()) {
+ Set<PackageElement> s = modulePackages
+ .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
+ s.add(p);
+ }
+ }
+
modules.addAll(modulePackages.keySet());
- showModules = (modulePackages.size() > 1);
+ showModules = !modules.isEmpty();
+ for (Set<PackageElement> pkgs : modulePackages.values()) {
+ packages.addAll(pkgs);
+ }
}
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(utils.getSpecifiedPackages());
- for (TypeElement aClass : utils.getSpecifiedClasses()) {
+ packages.addAll(getSpecifiedPackages());
+ for (TypeElement aClass : getSpecifiedClasses()) {
packages.add(utils.containingPackage(aClass));
}
}
@@ -629,7 +647,7 @@
if (docencoding == null) {
docencoding = encoding;
}
- typeElementCatalog = new TypeElementCatalog(utils.getSpecifiedClasses(), this);
+ typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2);
@@ -880,6 +898,35 @@
: utils.getFullyQualifiedName(te);
}
+ // cache these, as they are repeatedly called.
+ private Set<TypeElement> specifiedClasses = null;
+ private Set<PackageElement> specifiedPackages = null;
+ private Set<ModuleElement> specifiedModules = null;
+
+ public Set<TypeElement> getSpecifiedClasses() {
+ if (specifiedClasses == null) {
+ specifiedClasses = new LinkedHashSet<>(
+ ElementFilter.typesIn(docEnv.getSpecifiedElements()));
+ }
+ return specifiedClasses;
+ }
+
+ public Set<PackageElement> getSpecifiedPackages() {
+ if (specifiedPackages == null) {
+ specifiedPackages = new LinkedHashSet<>(
+ ElementFilter.packagesIn(docEnv.getSpecifiedElements()));
+ }
+ return specifiedPackages;
+ }
+
+ public Set<ModuleElement> getSpecifiedModules() {
+ if (specifiedModules == null) {
+ specifiedModules = new LinkedHashSet<>(
+ ElementFilter.modulesIn(docEnv.getSpecifiedElements()));
+ }
+ return specifiedModules;
+ }
+
/**
* Convenience method to obtain a resource from the doclet's
* {@link Resources resources}.
@@ -1146,6 +1193,4 @@
this.value2 = value2;
}
}
-
- public abstract Location getLocationForPackage(PackageElement pd);
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Mon Aug 29 08:53:32 2016 -0700
@@ -40,8 +40,8 @@
import jdk.javadoc.doclet.DocletEnvironment;
/**
- * This is a pseudo element wrapper for the root element, essentially to
- * associate overview documentation's DocCommentTree to this Element.
+ * This is a pseudo element wrapper for the overview element, essentially to
+ * associate overview documentation's DocCommentTree to this element.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -50,10 +50,10 @@
*/
public class OverviewElement implements Element {
- public final DocletEnvironment root;
+ public final DocletEnvironment docEnv;
- OverviewElement(DocletEnvironment root) {
- this.root = root;
+ OverviewElement(DocletEnvironment docEnv) {
+ this.docEnv = docEnv;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Mon Aug 29 08:53:32 2016 -0700
@@ -187,7 +187,7 @@
// TODO: implement using jx.l.model
public boolean isVisible(TypeElement te) {
- return toolEnv.isVisible((ClassSymbol)te);
+ return ((DocEnvImpl)(configuration.docEnv)).etable.isVisible(te);
}
// TODO: fix the caller
@@ -286,7 +286,7 @@
// TODO: investigate and reimplement without javac dependencies.
public boolean shouldDocument(Element e) {
- return toolEnv.shouldDocument(e);
+ return ((DocEnvImpl)(configuration.docEnv)).etable.shouldDocument(e);
}
//------------------Start of Serializable Implementation---------------------//
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -175,7 +175,7 @@
List<String> interfaceTableHeader = Arrays.asList(configuration.getText("doclet.Interface"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> ilist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> ilist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getInterfaces(packageElement))
: configuration.typeElementCatalog.interfaces(packageElement);
SortedSet<TypeElement> interfaces = utils.filterOutPrivateClasses(ilist, configuration.javafx);
@@ -200,7 +200,7 @@
configuration.getText("doclet.classes"));
List<String> classTableHeader = Arrays.asList(configuration.getText("doclet.Class"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> clist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> clist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getOrdinaryClasses(packageElement))
: configuration.typeElementCatalog.ordinaryClasses(packageElement);
SortedSet<TypeElement> classes = utils.filterOutPrivateClasses(clist, configuration.javafx);
@@ -225,7 +225,7 @@
configuration.getText("doclet.enums"));
List<String> enumTableHeader = Arrays.asList(configuration.getText("doclet.Enum"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> elist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> elist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getEnums(packageElement))
: configuration.typeElementCatalog.enums(packageElement);
SortedSet<TypeElement> enums = utils.filterOutPrivateClasses(elist, configuration.javafx);
@@ -251,7 +251,7 @@
List<String> exceptionTableHeader = Arrays.asList(configuration.getText("doclet.Exception"),
configuration.getText("doclet.Description"));
Set<TypeElement> iexceptions =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getExceptions(packageElement))
: configuration.typeElementCatalog.exceptions(packageElement);
SortedSet<TypeElement> exceptions = utils.filterOutPrivateClasses(iexceptions,
@@ -278,7 +278,7 @@
List<String> errorTableHeader = Arrays.asList(configuration.getText("doclet.Error"),
configuration.getText("doclet.Description"));
Set<TypeElement> ierrors =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getErrors(packageElement))
: configuration.typeElementCatalog.errors(packageElement);
SortedSet<TypeElement> errors = utils.filterOutPrivateClasses(ierrors, configuration.javafx);
@@ -305,7 +305,7 @@
configuration.getText("doclet.AnnotationType"),
configuration.getText("doclet.Description"));
SortedSet<TypeElement> iannotationTypes =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getAnnotationTypes(packageElement))
: configuration.typeElementCatalog.annotationTypes(packageElement);
SortedSet<TypeElement> annotationTypes = utils.filterOutPrivateClasses(iannotationTypes,
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -125,7 +125,7 @@
*/
public void build() throws IOException {
SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- rootclasses.addAll(configuration.docEnv.getIncludedClasses());
+ rootclasses.addAll(configuration.docEnv.getIncludedTypeElements());
if (!serialClassFoundToDocument(rootclasses)) {
//Nothing to document.
return;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
* questions.
*/
+var moduleSearchIndex;
var packageSearchIndex;
var typeSearchIndex;
var memberSearchIndex;
@@ -36,6 +37,14 @@
}
createElem(doc, tag, 'search.js');
+ $.get(pathtoroot + "module-search-index.zip")
+ .done(function() {
+ JSZipUtils.getBinaryContent(pathtoroot + "module-search-index.zip", function(e, data) {
+ var zip = new JSZip(data);
+ zip.load(data);
+ moduleSearchIndex = JSON.parse(zip.file("module-search-index.json").asText());
+ });
+ });
$.get(pathtoroot + "package-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "package-search-index.zip", function(e, data) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Mon Aug 29 08:53:32 2016 -0700
@@ -339,7 +339,7 @@
.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
margin:5px 0 10px 0px;
font-size:14px;
- font-family:'DejaVu Sans Mono',monospace;
+ font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
.serializedFormContainer dl.nameValue dt {
margin-left:1px;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java Mon Aug 29 08:53:32 2016 -0700
@@ -117,16 +117,16 @@
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator);
- buildTree(configuration.docEnv.getIncludedClasses());
+ buildTree(configuration.docEnv.getIncludedTypeElements());
}
/**
* Constructor. Build the Tree using the Root of this Javadoc run.
*
- * @param root Root of the Document.
+ * @param docEnv the DocletEnvironment.
* @param configuration The current configuration of the doclet.
*/
- public ClassTree(DocletEnvironment root, Configuration configuration) {
+ public ClassTree(DocletEnvironment docEnv, Configuration configuration) {
this.configuration = configuration;
this.utils = configuration.utils;
comparator = utils.makeClassUseComparator();
@@ -134,7 +134,7 @@
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator);
- buildTree(configuration.docEnv.getIncludedClasses());
+ buildTree(configuration.docEnv.getIncludedTypeElements());
}
/**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Mon Aug 29 08:53:32 2016 -0700
@@ -208,7 +208,7 @@
implementingClasses(intfc);
}
// Map methods, fields, constructors using a class.
- Set<TypeElement> classes = docEnv.getIncludedClasses();
+ Set<TypeElement> classes = docEnv.getIncludedTypeElements();
for (TypeElement aClass : classes) {
PackageElement pkg = elementUtils.getPackageOf(aClass);
mapAnnotations(classToPackageAnnotations, pkg, pkg);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -96,7 +96,7 @@
}
}
deprecatedMap.put(DeprElementKind.PACKAGE, pset);
- for (Element e : configuration.docEnv.getIncludedClasses()) {
+ for (Element e : configuration.docEnv.getIncludedTypeElements()) {
TypeElement te = (TypeElement)e;
SortedSet<Element> eset;
if (utils.isDeprecated(e)) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java Mon Aug 29 08:53:32 2016 -0700
@@ -37,6 +37,8 @@
*
*/
public class DocPaths {
+ /** The name of the file for all classes, without using frames, when --no-frames is specified. */
+ public static final DocPath ALLCLASSES = DocPath.create("allclasses.html");
/** The name of the file for all classes, using frames. */
public static final DocPath ALLCLASSES_FRAME = DocPath.create("allclasses-frame.html");
@@ -44,6 +46,10 @@
/** The name of the file for all classes, without using frames. */
public static final DocPath ALLCLASSES_NOFRAME = DocPath.create("allclasses-noframe.html");
+ public static DocPath AllClasses(boolean frames) {
+ return frames ? ALLCLASSES_NOFRAME : ALLCLASSES;
+ }
+
/** The name of the sub-directory for storing class usage info. */
public static final DocPath CLASS_USE = DocPath.create("class-use");
@@ -115,12 +121,22 @@
/** The name of the member search index zip file. */
public static final DocPath MEMBER_SEARCH_INDEX_ZIP = DocPath.create("member-search-index.zip");
+ /** The name of the module search index file. */
+ public static final DocPath MODULE_SEARCH_INDEX_JSON = DocPath.create("module-search-index.json");
+
+ /** The name of the module search index zipfile. */
+ public static final DocPath MODULE_SEARCH_INDEX_ZIP = DocPath.create("module-search-index.zip");
+
/** The name of the file for the overview frame. */
public static final DocPath OVERVIEW_FRAME = DocPath.create("overview-frame.html");
/** The name of the file for the overview summary. */
public static final DocPath OVERVIEW_SUMMARY = DocPath.create("overview-summary.html");
+ public static DocPath overviewSummary(boolean frames) {
+ return frames ? OVERVIEW_SUMMARY : INDEX;
+ }
+
/** The name of the file for the overview tree. */
public static final DocPath OVERVIEW_TREE = DocPath.create("overview-tree.html");
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,6 +28,7 @@
import java.util.*;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@@ -122,11 +123,11 @@
* given on the command line. Form separate list of those members depending
* upon their names.
*
- * @param root Root of the documemt.
+ * @param docEnv the doclet environment
*/
- protected void buildIndexMap(DocletEnvironment root) {
- Set<PackageElement> packages = utils.getSpecifiedPackages();
- Set<TypeElement> classes = root.getIncludedClasses();
+ protected void buildIndexMap(DocletEnvironment docEnv) {
+ Set<PackageElement> packages = configuration.getSpecifiedPackages();
+ Set<TypeElement> classes = docEnv.getIncludedTypeElements();
if (!classesOnly) {
if (packages.isEmpty()) {
Set<PackageElement> set = new HashSet<>();
@@ -148,6 +149,9 @@
putMembersInIndexMap(aClass);
}
}
+ if (configuration.showModules) {
+ addModulesToIndexMap();
+ }
}
}
@@ -190,6 +194,22 @@
}
/**
+ * Add all the modules to index map.
+ */
+ protected void addModulesToIndexMap() {
+ for (ModuleElement mdle : configuration.modules) {
+ String mdleName = mdle.getSimpleName().toString();
+ char ch = (mdleName.length() == 0)
+ ? '*'
+ : Character.toUpperCase(mdleName.charAt(0));
+ Character unicode = ch;
+ SortedSet<Element> list = indexmap.computeIfAbsent(unicode,
+ c -> new TreeSet<>(comparator));
+ list.add(mdle);
+ }
+ }
+
+ /**
* Should this element be added to the index map?
*/
protected boolean shouldAddToIndexMap(Element element) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java Mon Aug 29 08:53:32 2016 -0700
@@ -81,7 +81,7 @@
}
}
- protected void generatePackageListFile(DocletEnvironment root) {
+ protected void generatePackageListFile(DocletEnvironment docEnv) {
ArrayList<PackageElement> names = new ArrayList<>();
for (PackageElement pkg : configuration.packages) {
// if the -nodeprecated option is set and the package is marked as
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java Mon Aug 29 08:53:32 2016 -0700
@@ -100,7 +100,7 @@
public TypeElementCatalog(Iterable<TypeElement> typeElements, Configuration config) {
this(config);
for (TypeElement typeElement : typeElements) {
- addClassDoc(typeElement);
+ addTypeElement(typeElement);
}
}
@@ -127,39 +127,38 @@
*
* @param typeElement the TypeElement to add to the catalog.
*/
- public final void addClassDoc(TypeElement typeElement) {
+ public final void addTypeElement(TypeElement typeElement) {
if (typeElement == null) {
return;
}
- addClass(typeElement, allClasses);
+ addTypeElement(typeElement, allClasses);
if (utils.isOrdinaryClass(typeElement)) {
- addClass(typeElement, ordinaryClasses);
+ addTypeElement(typeElement, ordinaryClasses);
} else if (utils.isException(typeElement)) {
- addClass(typeElement, exceptions);
+ addTypeElement(typeElement, exceptions);
} else if (utils.isEnum(typeElement)) {
- addClass(typeElement, enums);
+ addTypeElement(typeElement, enums);
} else if (utils.isAnnotationType(typeElement)) {
- addClass(typeElement, annotationTypes);
+ addTypeElement(typeElement, annotationTypes);
} else if (utils.isError(typeElement)) {
- addClass(typeElement, errors);
+ addTypeElement(typeElement, errors);
} else if (utils.isInterface(typeElement)) {
- addClass(typeElement, interfaces);
+ addTypeElement(typeElement, interfaces);
}
}
/**
* Add the given class to the given map.
*
- * @param typeElement the ClassDoc to add to the catalog.
+ * @param typeElement the class to add to the catalog.
* @param map the Map to add the TypeElement to.
*/
- private void addClass(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
+ private void addTypeElement(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
PackageElement pkg = utils.containingPackage(typeElement);
- if (utils.isIncluded(pkg) || (configuration.nodeprecated && utils.isDeprecated(pkg))) {
+ if (utils.isSpecified(pkg) || configuration.nodeprecated && utils.isDeprecated(pkg)) {
// No need to catalog this class if it's package is
- // included on the command line or if -nodeprecated option is set
- // and the containing package is marked as deprecated.
+ // specified on the command line or if -nodeprecated option is set
return;
}
@@ -186,7 +185,7 @@
* @param packageElement the package to return the classes for.
*/
public SortedSet<TypeElement> allClasses(PackageElement packageElement) {
- return utils.isIncluded(packageElement)
+ return utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getEnclosedTypeElements(packageElement))
: getSet(allClasses, packageElement);
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Mon Aug 29 08:53:32 2016 -0700
@@ -86,7 +86,6 @@
import static com.sun.source.doctree.DocTree.Kind.*;
-import com.sun.source.util.SimpleDocTreeVisitor;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuilder.MAX_CONSTANT_VALUE_INDEX_LENGTH;
@@ -381,6 +380,10 @@
return e.getKind() == METHOD;
}
+ public boolean isModule(Element e) {
+ return e.getKind() == ElementKind.MODULE;
+ }
+
public boolean isPackage(Element e) {
return e.getKind() == ElementKind.PACKAGE;
}
@@ -1727,9 +1730,10 @@
/**
* Returns a Comparator for index file presentations, and are sorted as follows.
- * If comparing packages then simply compare the qualified names, otherwise
- * 1. sort on simple names of entities
- * 2. if equal, then compare the ElementKind ex: Package, Interface etc.
+ * If comparing modules then simply compare the simple names,
+ * comparing packages then simply compare the qualified names, otherwise
+ * 1. if equal, then compare the ElementKind ex: Module, Package, Interface etc.
+ * 2. sort on simple names of entities
* 3a. if equal and if the type is of ExecutableElement(Constructor, Methods),
* a case insensitive comparison of parameter the type signatures
* 3b. if equal, case sensitive comparison of the type signatures
@@ -1740,9 +1744,10 @@
public Comparator<Element> makeIndexUseComparator() {
return new Utils.ElementComparator<Element>() {
/**
- * Compare two given elements, if comparing two packages, return the
- * comparison of FullyQualifiedName, first sort on names, then on the
- * kinds, then on the parameters only if the type is an ExecutableElement,
+ * Compare two given elements, if comparing two modules, return the
+ * comparison of SimpleName, if comparing two packages, return the
+ * comparison of FullyQualifiedName, first sort on kinds, then on the
+ * names, then on the parameters only if the type is an ExecutableElement,
* the parameters are compared and finally the qualified names.
*
* @param e1 - an element.
@@ -1753,14 +1758,17 @@
@Override
public int compare(Element e1, Element e2) {
int result = 0;
+ if (isModule(e1) && isModule(e2)) {
+ return compareNames(e1, e2);
+ }
if (isPackage(e1) && isPackage(e2)) {
return compareFullyQualifiedNames(e1, e2);
}
- result = compareNames(e1, e2);
+ result = compareElementTypeKinds(e1, e2);
if (result != 0) {
return result;
}
- result = compareElementTypeKinds(e1, e2);
+ result = compareNames(e1, e2);
if (result != 0) {
return result;
}
@@ -1946,15 +1954,16 @@
final EnumMap<ElementKind, Integer> elementKindOrder;
public ElementComparator() {
elementKindOrder = new EnumMap<>(ElementKind.class);
- elementKindOrder.put(ElementKind.PACKAGE, 0);
- elementKindOrder.put(ElementKind.CLASS, 1);
- elementKindOrder.put(ElementKind.ENUM, 2);
- elementKindOrder.put(ElementKind.ENUM_CONSTANT, 3);
- elementKindOrder.put(ElementKind.INTERFACE, 4);
- elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 5);
- elementKindOrder.put(ElementKind.FIELD, 6);
- elementKindOrder.put(ElementKind.CONSTRUCTOR, 7);
- elementKindOrder.put(ElementKind.METHOD, 8);
+ elementKindOrder.put(ElementKind.MODULE, 0);
+ elementKindOrder.put(ElementKind.PACKAGE, 1);
+ elementKindOrder.put(ElementKind.CLASS, 2);
+ elementKindOrder.put(ElementKind.ENUM, 3);
+ elementKindOrder.put(ElementKind.ENUM_CONSTANT, 4);
+ elementKindOrder.put(ElementKind.INTERFACE, 5);
+ elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 6);
+ elementKindOrder.put(ElementKind.FIELD, 7);
+ elementKindOrder.put(ElementKind.CONSTRUCTOR, 8);
+ elementKindOrder.put(ElementKind.METHOD, 9);
}
protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
@@ -2220,31 +2229,6 @@
return oset;
}
- // cache these two as they are repeatedly called.
- private Set<TypeElement> specifiedClasses = null;
- private Set<PackageElement> specifiedPackages = null;
-
- private void initSpecifiedElements() {
- specifiedClasses = new LinkedHashSet<>(
- ElementFilter.typesIn(configuration.docEnv.getSpecifiedElements()));
- specifiedPackages = new LinkedHashSet<>(
- ElementFilter.packagesIn(configuration.docEnv.getSpecifiedElements()));
- }
-
- public Set<TypeElement> getSpecifiedClasses() {
- if (specifiedClasses == null || specifiedPackages == null) {
- initSpecifiedElements();
- }
- return specifiedClasses;
- }
-
- public Set<PackageElement> getSpecifiedPackages() {
- if (specifiedClasses == null || specifiedPackages == null) {
- initSpecifiedElements();
- }
- return specifiedPackages;
- }
-
private final HashMap<Element, SortedSet<TypeElement>> cachedClasses = new HashMap<>();
/**
* Returns a list containing classes and interfaces,
@@ -2404,6 +2388,11 @@
if (snvisitor == null) {
snvisitor = new SimpleElementVisitor9<String, Void>() {
@Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public String visitModule(ModuleElement e, Void p) {
+ return e.getSimpleName().toString();
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
public String visitType(TypeElement e, Void p) {
StringBuilder sb = new StringBuilder(e.getSimpleName());
Element enclosed = e.getEnclosingElement();
@@ -2577,6 +2566,34 @@
return configuration.docEnv.isIncluded(e);
}
+ private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;
+ public boolean isSpecified(Element e) {
+ if (specifiedVisitor == null) {
+ specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitModule(ModuleElement e, Void p) {
+ return configuration.getSpecifiedModules().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ return configuration.getSpecifiedPackages().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ return configuration.getSpecifiedClasses().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ protected Boolean defaultAction(Element e, Void p) {
+ return false;
+ }
+ };
+ }
+ return specifiedVisitor.visit(e);
+ }
+
/**
* package name, an unnamed package is returned as <Unnamed>
* @param pkg
@@ -2979,6 +2996,10 @@
return out;
}
+ public ModuleElement containingModule(Element e) {
+ return elementUtils.getModuleOf(e);
+ }
+
public PackageElement containingPackage(Element e) {
return elementUtils.getPackageOf(e);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/AccessKind.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.tool;
+
+/**
+ * The access value kinds.
+ */
+
+public enum AccessKind {
+ /** Limits access to public entities */
+ PUBLIC,
+ /** Limits access to public and protected entities */
+ PROTECTED,
+ /** Limits access to public, protected and package private entities */
+ PACKAGE,
+ /** No limits */
+ PRIVATE;
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -25,7 +25,6 @@
package jdk.javadoc.internal.tool;
-import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -33,6 +32,7 @@
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
@@ -41,7 +41,6 @@
import com.sun.source.util.DocTrees;
import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import jdk.javadoc.doclet.DocletEnvironment;
/**
@@ -60,202 +59,44 @@
*/
public class DocEnvImpl implements DocletEnvironment {
- /**
- * list of classes specified on the command line.
- */
- private Set<TypeElement> cmdLineClasses;
-
- /**
- * list of packages specified on the command line.
- */
- private Set<PackageElement> cmdLinePackages;
+ public final ElementsTable etable;
public final ToolEnvironment toolEnv;
/**
- * Constructor used when reading source files.
- *
- * @param toolEnv the documentation environment, state for this javadoc run
- * @param classes list of classes specified on the commandline
- * @param packages list of package names specified on the commandline
- */
- public DocEnvImpl(ToolEnvironment toolEnv, List<JCClassDecl> classes, List<String> packages) {
- this.toolEnv = toolEnv;
- setPackages(toolEnv, packages);
- setClasses(toolEnv, classes);
- }
-
- /**
- * Constructor used when reading class files.
+ * Construct a doclet environment.
*
- * @param toolEnv the documentation environment, state for this javadoc run
- * @param classes list of class names specified on the commandline
+ * @param toolEnv the tool environment
+ * @param etable the includes table, providing all the information
+ * with respect to specified, included/selected elements.
*/
- public DocEnvImpl(ToolEnvironment toolEnv, List<String> classes) {
- //super(env, null);
+ public DocEnvImpl(ToolEnvironment toolEnv, ElementsTable etable) {
this.toolEnv = toolEnv;
-
- Set<TypeElement> classList = new LinkedHashSet<>();
- for (String className : classes) {
- TypeElement c = toolEnv.loadClass(className);
- if (c == null)
- toolEnv.error(null, "javadoc.class_not_found", className);
- else
- classList.add(c);
- }
- cmdLineClasses = classList;
+ this.etable = etable;
}
- /**
- * Initialize classes information. Those classes are input from
- * command line.
- *
- * @param toolEnv the compilation environment
- * @param classes a list of ClassDeclaration
- */
- private void setClasses(ToolEnvironment toolEnv, List<JCClassDecl> classes) {
- Set<TypeElement> result = new LinkedHashSet<>();
- classes.stream().filter((def) -> (toolEnv.shouldDocument(def.sym))).forEach((def) -> {
- TypeElement te = (TypeElement)def.sym;
- if (te != null) {
- toolEnv.setIncluded((Element)def.sym);
- result.add(te);
- }
- });
- cmdLineClasses = Collections.unmodifiableSet(result);
+ @Override
+ public Set<ModuleElement> getIncludedModuleElements() {
+ return etable.getIncludedModuleElements();
}
- /**
- * Initialize packages information.
- *
- * @param toolEnv the compilation environment
- * @param packages a list of package names (String)
- */
- private void setPackages(ToolEnvironment toolEnv, List<String> packages) {
- Set<PackageElement> packlist = new LinkedHashSet<>();
- packages.stream().forEach((name) -> {
- PackageElement pkg = getElementUtils().getPackageElement(name);
- if (pkg != null) {
- toolEnv.setIncluded(pkg);
- packlist.add(pkg);
- } else {
- toolEnv.warning("main.no_source_files_for_package", name);
- }
- });
- cmdLinePackages = Collections.unmodifiableSet(packlist);
- }
-
- /**
- * Packages specified on the command line.
- */
- public Set<PackageElement> specifiedPackages() {
- return cmdLinePackages;
+ @Override
+ public Set<PackageElement> getIncludedPackageElements() {
+ return etable.getIncludedPackageElements();
}
/**
- * Classes and interfaces specified on the command line,
- * including their inner classes
- */
- public Set<TypeElement> specifiedClasses() {
- Set<TypeElement> out = new LinkedHashSet<>();
- cmdLineClasses.stream().forEach((te) -> {
- toolEnv.addAllClasses(out, te, true);
- });
- return out;
- }
-
- private Set<TypeElement> classesToDocument = null;
- /**
- * Return all classes and interfaces (including those inside
+ * Return all TypeElements (including those inside
* packages) to be documented.
*/
- public Set<TypeElement> getIncludedClasses() {
- if (classesToDocument == null) {
- Set<TypeElement> classes = new LinkedHashSet<>();
-
- cmdLineClasses.stream().forEach((te) -> {
- toolEnv.addAllClasses(classes, te, true);
- });
- cmdLinePackages.stream().forEach((pkg) -> {
- toolEnv.addAllClasses(classes, pkg);
- });
- classesToDocument = Collections.unmodifiableSet(classes);
- }
- return classesToDocument;
- }
-
- /**
- * Return the name of this item.
- *
- * @return the string <code>"*RootDocImpl*"</code>.
- */
- public String name() {
- return "*RootDocImpl*";
- }
-
- /**
- * Return the name of this Doc item.
- *
- * @return the string <code>"*RootDocImpl*"</code>.
- */
- public String qualifiedName() {
- return "*RootDocImpl*";
+ @Override
+ public Set<TypeElement> getIncludedTypeElements() {
+ return etable.getIncludedTypeElements();
}
- /**
- * Return true if this Element is included in the active set.
- * RootDocImpl isn't even a program entity so it is always false.
- */
@Override
public boolean isIncluded(Element e) {
- return toolEnv.isIncluded(e);
- }
-
-// Note: these reporting methods are no longer used.
-// /**
-// * Print error message, increment error count.
-// *
-// * @param msg message to print
-// */
-// public void printError(String msg) {
-// env.printError(msg);
-// }
-//
-// /**
-// * Print error message, increment error count.
-// *
-// * @param msg message to print
-// */
-// public void printError(DocTreePath path, String msg) {
-// env.printError(path, msg);
-// }
-//
-// public void printError(Element e, String msg) {
-// env.printError(e, msg);
-// }
-//
-// public void printWarning(Element e, String msg) {
-// env.printWarning(e, msg);
-// }
-//
-// public void printNotice(Element e, String msg) {
-// env.printNotice(e, msg);
-// }
-//
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param msg message to print
-// */
-// public void printWarning(String msg) {
-// env.printWarning(msg);
-// }
-
- /**
- * Return the current file manager.
- */
- public JavaFileManager getFileManager() {
- return toolEnv.fileManager;
+ return etable.isIncluded(e);
}
@Override
@@ -278,12 +119,9 @@
@Override
public Set<Element> getSpecifiedElements() {
Set<Element> out = new LinkedHashSet<>();
- specifiedPackages().stream().forEach((pe) -> {
- out.add(pe);
- });
- specifiedClasses().stream().forEach((e) -> {
- out.add(e);
- });
+ out.addAll(etable.getSpecifiedModuleElements());
+ out.addAll(etable.getSpecifiedPackageElements());
+ out.addAll(etable.getSpecifiedTypeElements());
return out;
}
@@ -301,4 +139,9 @@
public SourceVersion getSourceVersion() {
return Source.toSourceVersion(toolEnv.source);
}
+
+ @Override
+ public ModuleMode getModuleMode() {
+ return etable.getModuleMode();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.javadoc.internal.tool;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.ExportsDirective;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds.Kind;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.comp.Modules;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
+
+/**
+ * This class manages elements specified on the command line, and
+ * produces "specified" and "included" data sets, needed by the
+ * doclet environment, as well as querying an elements' visibility
+ * or inclusion.
+ *
+ * A. Initialization phase: the class is initialized with the
+ * options table by the caller. Some program elements may not
+ * be specified via specific options, such as packages, classes,
+ * these are set with the use of setter methods, such setClassArgList
+ * and setClassDeclList.
+ *
+ * B. Scan and decode phase: this is performed by scanSpecifiedItems,
+ * to identify the modules specified on the command line, modules
+ * specified with qualified packages and qualified subpackages, the
+ * modules so identified are used to initialize the module system.
+ *
+ * C. Intermediate phase: before the final analysis can be done,
+ * intermediate methods can be used to get specified elements from
+ * the initialization phase, typically used to parse sources or packages
+ * specified on the command line.
+ *
+ * D. Analysis phase: the final analysis is performed to determine
+ * the packages that ought to be included, as follows:
+ *
+ * 1. computes the specified modules, by considering the option
+ * "expand-requires", this must be done exhaustively, as the package
+ * computation phase expects a completed module graph, in order to
+ * check the target of a qualified export is in the included set.
+ *
+ * 2. computes the packages that must be documented, by considering
+ * the option "show-packages", also if only exported packages are
+ * to be considered, then also check for qualified packages, and
+ * include only those packages whose target is in the included set.
+ *
+ * 3. compute the specified packages, as part of this, first compute
+ * the subpackages and exclude any packages, if required.
+ *
+ * 4. Finally, compute the types found by previous parsing steps,
+ * noting that, all enclosed types (nested types) must also be
+ * considered.
+ *
+ * E. Finally, this class provides methods to obtain the specified sets,
+ * which are frozen and cached in the analysis phase, the included
+ * sets, are computed lazily and cached for future use. An element
+ * can be checked if it should be documented, in which case, the
+ * element is checked against the included set and the result is
+ * cached, for performance reasons.
+ *
+ * Definitions:
+ * Fully included: an element is included and some or parts
+ * of it components are included implicitly, subject to a
+ * selection criteria of its enclosed children.
+ *
+ * Included: if the item should be documented.
+ *
+ * Rules for processing:
+ *
+ * 1. A specified element, meaning an element given on the
+ * command-line, and exposed via getSpecifiedElements()
+ * 2. Expand-contents, an internal pseudo term, meaning
+ * it is part of the recursive expansion of specified
+ * elements, meaning, the modules are expanded first, then
+ * the packages contained in the expanded modules, and then
+ * the types contained within the packages, to produce the
+ * collections returned by the methods
+ * getInclude{Module|Package|Type}Elements(), this is a
+ * downward expansion.
+ * 3. An included element, meaning it should be documented, and
+ * exposed via isIncluded, this enclosing element (module, package)
+ * is recursively included.
+ */
+public class ElementsTable {
+
+ private final ToolEnvironment toolEnv;
+ private final Symtab syms;
+ private final Names names;
+ private final JavaFileManager fm;
+ private final Location location;
+ private final Modules modules;
+ private final Map<ToolOption, Object> opts;
+
+ private final Map<String, Entry> entries = new LinkedHashMap<>();
+
+ // specified elements
+ private Set<ModuleElement> specifiedModuleElements = new LinkedHashSet<>();
+ private Set<PackageElement> specifiedPackageElements = new LinkedHashSet<>();
+ private Set<TypeElement> specifiedTypeElements =new LinkedHashSet<>();
+
+ // included elements
+ private Set<ModuleElement> includedModuleElements = null;
+ private Set<PackageElement> includedPackageElements = null;
+ private Set<TypeElement> includedTypeElements = null;
+
+ // cmdline specifiers
+ private Set<ModulePackage> cmdLinePackages = new LinkedHashSet<>();
+ private Set<ModulePackage> excludePackages = new LinkedHashSet<>();
+ private Set<ModulePackage> subPackages = new LinkedHashSet<>();
+
+ private List<JCClassDecl> classDecList = Collections.emptyList();
+ private List<String> classArgList = Collections.emptyList();
+ private com.sun.tools.javac.util.List<JCCompilationUnit> classTreeList = null;
+
+ private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
+
+ private final ModifierFilter accessFilter;
+
+ private final AccessKind expandRequires;
+
+ final boolean xclasses;
+
+ /**
+ * Creates the table to manage included and excluded elements.
+ *
+ * @param context the context to locate commonly used objects
+ * @param location the location used to locate source files
+ */
+ ElementsTable(Context context, Map<ToolOption, Object> opts) {
+ this.toolEnv = ToolEnvironment.instance(context);
+ this.syms = Symtab.instance(context);
+ this.names = Names.instance(context);
+ this.fm = toolEnv.fileManager;
+ this.modules = Modules.instance(context);
+ this.opts = opts;
+ this.location = modules.multiModuleMode
+ ? StandardLocation.MODULE_SOURCE_PATH
+ : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
+ ? StandardLocation.SOURCE_PATH
+ : StandardLocation.CLASS_PATH;
+ getEntry("").excluded = false;
+
+ accessFilter = new ModifierFilter(opts);
+ xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false);
+ expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES);
+ }
+
+ /**
+ * Returns the module documentation level mode.
+ * @return the module documentation level mode
+ */
+ public ModuleMode getModuleMode() {
+ switch(accessFilter.getAccessValue(ElementKind.MODULE)) {
+ case PACKAGE: case PRIVATE:
+ return DocletEnvironment.ModuleMode.ALL;
+ default:
+ return DocletEnvironment.ModuleMode.API;
+ }
+ }
+
+ /**
+ * Returns the selected/included module elements.
+ * A module is fully included,
+ * - is specified on the command line --module
+ * - is derived from the module graph, that is, by expanding the
+ * requires directive, based on --expand-requires
+ *
+ * A module is included if an enclosed package or type is
+ * specified on the command line.
+ * @return the included module elements
+ */
+ public Set<ModuleElement> getIncludedModuleElements() {
+ return includedModuleElements;
+ }
+
+ /**
+ * Returns the selected/included package elements.
+ * A package is fully included,
+ * - is specified on the command line
+ * - is derived from expanding -subpackages
+ * - can be documented in a fully included module based on --show-packages
+ *
+ * A package is included, if an enclosed package or a type is specified on
+ * the command line.
+ *
+ * @return the included package elements
+ */
+ public Set<PackageElement> getIncludedPackageElements() {
+ return includedPackageElements;
+ }
+
+ /**
+ * Returns the selected/included type elements (including those
+ * within specified or included packages) to be documented.
+ * A type is fully included if
+ * - is specified on the command line with -sourcepath
+ * - is visible with --show-types filter
+ * A nested type is fully included if
+ * - is visible with --show-types filter
+ * - is enclosed in a fully included type
+ *
+ * @return the included type elements
+ * to be documented
+ */
+ public Set<TypeElement> getIncludedTypeElements() {
+ return includedTypeElements;
+ }
+
+ /**
+ * Returns a set of module elements specified on the
+ * command line.
+ * @return the set of module elements specified on the
+ * command line
+ */
+ public Set<ModuleElement> getSpecifiedModuleElements() {
+ return specifiedModuleElements;
+ }
+
+ /**
+ * Returns a set of package elements specified on the
+ * command line. These may also contain children packages
+ * if specified with -subpackage.
+ *
+ * @return the set of package elements specified on the
+ * command line
+ */
+ public Set<PackageElement> getSpecifiedPackageElements() {
+ return specifiedPackageElements;
+ }
+
+ /**
+ * Returns a set of type elements specified on the
+ * command line, including any inner classes.
+ *
+ * @return the set of type elements specified on the command line
+ */
+ public Set<TypeElement> getSpecifiedTypeElements() {
+ return specifiedTypeElements;
+ }
+
+ private IncludedVisitor includedVisitor = null;
+
+ /**
+ * Returns true if the given element is included or selected for
+ * consideration.
+ * This method accumulates elements in the cache as enclosed elements of
+ * fully included elements are tested.
+ * A member (constructor, method, field) is included if
+ * - it is visible in a fully included type (--show-members)
+ *
+ * @param e the element in question
+ *
+ * @see getIncludedModuleElements
+ * @see getIncludedPackageElements
+ * @see getIncludedTypeElements
+ *
+ * @return true if included
+ */
+ public boolean isIncluded(Element e) {
+ if (e == null) {
+ return false;
+ }
+ if (includedVisitor == null) {
+ includedVisitor = new IncludedVisitor();
+ }
+ return includedVisitor.visit(e);
+ }
+
+ /**
+ * Performs the final computation and freezes the collections.
+ * This is a terminal operation, thus no further modifications
+ * are allowed to the specified data sets.
+ *
+ * @throws IOException if an error occurs
+ */
+ void analyze() throws IOException {
+ // compute the specified element, by expanding module dependencies
+ computeSpecifiedModules();
+
+ // compute all specified packages and subpackages
+ computeSpecifiedPackages();
+
+ // compute the specified types
+ computeSpecifiedTypes();
+
+ // compute the packages belonging to all the specified modules
+ Set<PackageElement> expandedModulePackages = computeModulePackages();
+ initializeIncludedSets(expandedModulePackages);
+
+ }
+
+ ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
+ this.classTreeList = classTrees;
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ ElementsTable scanSpecifiedItems() throws IOException {
+
+ // scan modules specified on the command line
+ List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
+ s -> Collections.EMPTY_LIST);
+ List<String> mlist = new ArrayList<>();
+ for (String m : moduleNames) {
+ Location moduleLoc = fm.getModuleLocation(location, m);
+ if (moduleLoc == null) {
+ toolEnv.error("main.module_not_found", m);
+ } else {
+ mlist.add(m);
+ ModuleSymbol msym = syms.enterModule(names.fromString(m));
+ specifiedModuleElements.add((ModuleElement) msym);
+ }
+ }
+
+ // scan for modules with qualified packages
+ cmdLinePackages.stream()
+ .filter((mpkg) -> (mpkg.hasModule()))
+ .forEachOrdered((mpkg) -> {
+ mlist.add(mpkg.moduleName);
+ });
+
+ // scan for modules with qualified subpackages
+ ((List<String>)opts.computeIfAbsent(ToolOption.SUBPACKAGES, v -> Collections.EMPTY_LIST))
+ .stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> {
+ subPackages.add(mpkg);
+ if (mpkg.hasModule()) {
+ mlist.add(mpkg.moduleName);
+ }
+ });
+
+ // all the modules specified on the command line have been scraped
+ // init the module systems
+ modules.addExtraAddModules(mlist.toArray(new String[mlist.size()]));
+ modules.initModules(this.classTreeList);
+
+ return this;
+ }
+
+ /**
+ * Returns the includes table after setting a class names specified on the command line.
+ *
+ * @param classList
+ * @return the include table
+ */
+ ElementsTable setClassArgList(List<String> classList) {
+ classArgList = classList;
+ return this;
+ }
+
+ /**
+ * Returns the includes table after setting the parsed class names.
+ *
+ * @param classesDecList
+ * @return the include table
+ */
+ ElementsTable setClassDeclList(List<JCClassDecl> classesDecList) {
+ this.classDecList = classesDecList;
+ return this;
+ }
+
+ /**
+ * Returns an includes table after setting the specified package
+ * names.
+ * @param packageNames packages on the command line
+ * @return the includes table after setting the specified package
+ * names
+ */
+ ElementsTable packages(Collection<String> packageNames) {
+ packageNames.stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> cmdLinePackages.add(mpkg));
+ return this;
+ }
+
+ /**
+ * Returns the aggregate set of included packages and specified
+ * sub packages.
+ *
+ * @return the aggregate set of included packages and specified
+ * sub packages
+ */
+ Iterable<ModulePackage> getPackagesToParse() throws IOException {
+ List<ModulePackage> result = new ArrayList<>();
+ result.addAll(cmdLinePackages);
+ result.addAll(subPackages);
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void computeSubpackages() throws IOException {
+ ((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST))
+ .stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> excludePackages.add(mpkg));
+
+ excludePackages.forEach((p) -> {
+ getEntry(p).excluded = true;
+ });
+
+ for (ModulePackage modpkg : subPackages) {
+ Location packageLocn = getLocation(modpkg);
+ for (JavaFileObject fo : fm.list(packageLocn, modpkg.packageName, sourceKinds, true)) {
+ String binaryName = fm.inferBinaryName(packageLocn, fo);
+ String pn = getPackageName(binaryName);
+ String simpleName = getSimpleName(binaryName);
+ Entry e = getEntry(pn);
+ if (!e.isExcluded() && isValidClassName(simpleName)) {
+ ModuleSymbol msym = (modpkg.hasModule())
+ ? syms.getModule(names.fromString(modpkg.moduleName))
+ : findModuleOfPackageName(modpkg.packageName);
+
+ if (msym != null && !msym.isUnnamed()) {
+ syms.enterPackage(msym, names.fromString(pn));
+ ModulePackage npkg = new ModulePackage(msym.toString(), pn);
+ cmdLinePackages.add(npkg);
+ } else {
+ cmdLinePackages.add(e.modpkg);
+ }
+ e.files = (e.files == null
+ ? com.sun.tools.javac.util.List.of(fo)
+ : e.files.prepend(fo));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the "requires" modules for the target module.
+ * @param mdle the target module element
+ * @param isPublic true gets all the public requires, otherwise
+ * gets all the non-public requires
+ *
+ * @return a set of modules
+ */
+ private Set<ModuleElement> getModuleRequires(ModuleElement mdle, boolean isPublic) {
+ Set<ModuleElement> result = new HashSet<>();
+ for (RequiresDirective rd : ElementFilter.requiresIn(mdle.getDirectives())) {
+ if (isPublic && rd.isPublic()) {
+ result.add(rd.getDependency());
+ }
+ if (!isPublic && !rd.isPublic()) {
+ result.add(rd.getDependency());
+ }
+ }
+ return result;
+ }
+
+ private void computeSpecifiedModules() {
+ if (expandRequires == null) { // no expansion requested
+ specifiedModuleElements = Collections.unmodifiableSet(specifiedModuleElements);
+ return;
+ }
+
+ final boolean expandAll = expandRequires.equals(AccessKind.PRIVATE)
+ || expandRequires.equals(AccessKind.PACKAGE);
+
+ Set<ModuleElement> result = new LinkedHashSet<>();
+ ListBuffer<ModuleElement> queue = new ListBuffer<>();
+
+ // expand each specified module
+ for (ModuleElement mdle : getSpecifiedModuleElements()) {
+ result.add(mdle); // a specified module is included
+ queue.append(mdle);
+ Set<ModuleElement> publicRequires = getModuleRequires(mdle, true);
+ result.addAll(publicRequires);
+ // add all requires public
+ queue.addAll(publicRequires);
+
+ if (expandAll) {
+ // add non-public requires if needed
+ result.addAll(getModuleRequires(mdle, !expandAll));
+ }
+ }
+
+ // compute the transitive closure of all the requires public
+ for (ModuleElement m = queue.poll() ; m != null ; m = queue.poll()) {
+ for (ModuleElement mdle : getModuleRequires(m, true)) {
+ if (!result.contains(mdle)) {
+ result.add(mdle);
+ queue.append(mdle);
+ }
+ }
+ }
+ specifiedModuleElements = Collections.unmodifiableSet(result);
+ }
+
+ private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws IOException {
+ Set<PackageElement> result = new HashSet<>();
+ ModuleSymbol msym = (ModuleSymbol)mdle;
+ Location msymloc = fm.getModuleLocation(location, msym.name.toString());
+ for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
+ if (fo.getName().endsWith("module-info.java"))
+ continue;
+ String binaryName = fm.inferBinaryName(msymloc, fo);
+ String pn = getPackageName(binaryName);
+ PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
+ result.add((PackageElement)psym);
+ }
+ return result;
+ }
+
+ private Set<PackageElement> computeModulePackages() throws IOException {
+ final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+ final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
+ accessValue == AccessKind.PRIVATE);
+
+ Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
+
+ for (ModuleElement mdle : specifiedModuleElements) {
+ // add all exported packages belonging to a specified module
+ if (specifiedModuleElements.contains(mdle)) {
+ List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+ for (ExportsDirective export : exports) {
+ expandedModulePackages.add(export.getPackage());
+ }
+ }
+
+ // add all packages specified on the command line
+ // belonging to this module
+ if (!cmdLinePackages.isEmpty()) {
+ for (ModulePackage modpkg : cmdLinePackages) {
+ PackageElement pkg = toolEnv.elements.getPackageElement(mdle,
+ modpkg.packageName);
+ if (pkg != null) {
+ expandedModulePackages.add(pkg);
+ }
+ }
+ }
+
+ if (!documentAllModulePackages) {
+ List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+ // check exported packages
+ for (ExportsDirective export : exports) {
+ List<? extends ModuleElement> targetModules = export.getTargetModules();
+ if (targetModules == null) { // no qualified exports, add 'em all
+ expandedModulePackages.add(export.getPackage());
+ } else { // qualified export, add only if target module is being considered
+ for (ModuleElement target : targetModules) {
+ if (specifiedModuleElements.contains(target)) {
+ expandedModulePackages.add(export.getPackage());
+ }
+ }
+ }
+ }
+ } else { // add all exported and module private packages
+ List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+ expandedModulePackages.addAll(packages);
+ expandedModulePackages.addAll(getAllModulePackages(mdle));
+ }
+ }
+ return expandedModulePackages;
+ }
+
+ private void initializeIncludedSets(Set<PackageElement> expandedModulePackages) {
+
+ // process modules
+ Set<ModuleElement> imodules = new LinkedHashSet<>();
+ // add all the expanded modules
+ imodules.addAll(specifiedModuleElements);
+
+ // process packages
+ Set<PackageElement> ipackages = new LinkedHashSet<>();
+ // add all packages belonging to expanded modules
+ ipackages.addAll(expandedModulePackages);
+ // add all specified packages
+ specifiedPackageElements.forEach(pkg -> {
+ ModuleElement mdle = toolEnv.elements.getModuleOf(pkg);
+ imodules.add(mdle);
+ ipackages.add(pkg);
+ });
+
+ // process types
+ Set<TypeElement> iclasses = new LinkedHashSet<>();
+ // add all types enclosed in expanded modules and packages
+ ipackages.forEach((pkg) -> {
+ addAllClasses(iclasses, pkg);
+ });
+ // add all types and its nested types
+ specifiedTypeElements.forEach((klass) -> {
+ ModuleElement mdle = toolEnv.elements.getModuleOf(klass);
+ if (!mdle.isUnnamed())
+ imodules.add(mdle);
+ PackageElement pkg = toolEnv.elements.getPackageOf(klass);
+ if (!pkg.isUnnamed())
+ ipackages.add(pkg);
+ addAllClasses(iclasses, klass, true);
+ });
+
+ // all done, freeze the collections
+ includedModuleElements = Collections.unmodifiableSet(imodules);
+ includedPackageElements = Collections.unmodifiableSet(ipackages);
+ includedTypeElements = Collections.unmodifiableSet(iclasses);
+ }
+
+ /**
+ * Computes the included packages and freezes the specified packages list.
+ */
+ private void computeSpecifiedPackages() throws IOException {
+
+ computeSubpackages();
+
+ Set<PackageElement> packlist = new LinkedHashSet<>();
+ cmdLinePackages.forEach((modpkg) -> {
+ ModuleElement mdle = null;
+ PackageElement pkg;
+ if (modpkg.hasModule()) {
+ mdle = toolEnv.elements.getModuleElement(modpkg.moduleName);
+ pkg = toolEnv.elements.getPackageElement(mdle, modpkg.packageName);
+ } else {
+ pkg = toolEnv.elements.getPackageElement(modpkg.toString());
+ }
+
+ if (pkg != null) {
+ packlist.add(pkg);
+ } else {
+ toolEnv.warning("main.package_not_found", modpkg.toString());
+ }
+ });
+ specifiedPackageElements = Collections.unmodifiableSet(packlist);
+ }
+
+ /**
+ * Adds all classes as well as inner classes, to the specified
+ * list.
+ */
+ private void computeSpecifiedTypes() {
+ Set<TypeElement> classes = new LinkedHashSet<>();
+ classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> {
+ TypeElement te = (TypeElement) def.sym;
+ if (te != null) {
+ addAllClasses(classes, te, true);
+ }
+ });
+ classArgList.forEach((className) -> {
+ TypeElement te = toolEnv.loadClass(className);
+ if (te == null) {
+ toolEnv.error("javadoc.class_not_found", className);
+ } else {
+ addAllClasses(classes, te, true);
+ }
+ });
+ specifiedTypeElements = Collections.unmodifiableSet(classes);
+ }
+
+ private void addFilesForParser(Collection<JavaFileObject> result,
+ Collection<ModulePackage> collection, boolean recurse) throws IOException {
+ for (ModulePackage modpkg : collection) {
+ toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString());
+ List<JavaFileObject> files = getFiles(modpkg, recurse);
+ if (files.isEmpty()) {
+ toolEnv.error("main.no_source_files_for_package", modpkg.toString());
+ } else {
+ result.addAll(files);
+ }
+ }
+ }
+
+ /**
+ * Returns an aggregated list of java file objects from the items
+ * specified on the command line. The packages specified should not
+ * recurse, however sub-packages should recurse into the sub directories.
+ * @return a list of java file objects
+ * @throws IOException if an error occurs
+ */
+ List<JavaFileObject> getFilesToParse() throws IOException {
+ List<JavaFileObject> result = new ArrayList<>();
+ addFilesForParser(result, cmdLinePackages, false);
+ addFilesForParser(result, subPackages, true);
+ return result;
+ }
+
+ /**
+ * Returns the set of source files for a package.
+ *
+ * @param packageName the specified package
+ * @return the set of file objects for the specified package
+ * @throws IOException if an error occurs while accessing the files
+ */
+ private List<JavaFileObject> getFiles(ModulePackage modpkg, boolean recurse) throws IOException {
+ Entry e = getEntry(modpkg);
+ // The files may have been found as a side effect of searching for subpackages
+ if (e.files != null) {
+ return e.files;
+ }
+
+ ListBuffer<JavaFileObject> lb = new ListBuffer<>();
+ Location packageLocn = getLocation(modpkg);
+ if (packageLocn == null) {
+ return Collections.emptyList();
+ }
+ String pname = modpkg.packageName;
+ for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
+ String binaryName = fm.inferBinaryName(packageLocn, fo);
+ String simpleName = getSimpleName(binaryName);
+ if (isValidClassName(simpleName)) {
+ lb.append(fo);
+ }
+ }
+
+ return lb.toList();
+ }
+
+ private ModuleSymbol findModuleOfPackageName(String packageName) {
+ Name pack = names.fromString(packageName);
+ for (ModuleSymbol msym : modules.allModules()) {
+ PackageSymbol p = syms.getPackage(msym, pack);
+ if (p != null && !p.members().isEmpty()) {
+ return msym;
+ }
+ }
+ return null;
+ }
+
+ private Location getLocation(ModulePackage modpkg) throws IOException {
+ if (location != StandardLocation.MODULE_SOURCE_PATH) {
+ return location;
+ }
+
+ if (modpkg.hasModule()) {
+ return fm.getModuleLocation(location, modpkg.moduleName);
+ }
+ // TODO: handle invalid results better.
+ ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
+ if (msym == null) {
+ return null;
+ }
+ return fm.getModuleLocation(location, msym.name.toString());
+ }
+
+ private Entry getEntry(String name) {
+ return getEntry(new ModulePackage(name));
+ }
+
+ private Entry getEntry(ModulePackage modpkg) {
+ Entry e = entries.get(modpkg.packageName);
+ if (e == null) {
+ entries.put(modpkg.packageName, e = new Entry(modpkg));
+ }
+ return e;
+ }
+
+ private String getPackageName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? "" : name.substring(0, lastDot));
+ }
+
+ private String getSimpleName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? name : name.substring(lastDot + 1));
+ }
+
+ /**
+ * Adds all inner classes of this class, and their inner classes recursively, to the list
+ */
+ private void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
+ ClassSymbol klass = (ClassSymbol)typeElement;
+ try {
+ // eliminate needless checking, do this first.
+ if (list.contains(klass)) return;
+ if (toolEnv.isSynthetic(klass)) return;
+ // ignore classes with invalid Java class names
+ if (!JavadocTool.isValidClassName(klass.name.toString())) return;
+ if (filtered && !shouldDocument(klass)) return;
+ list.add(klass);
+ for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kind.TYP) {
+ ClassSymbol s = (ClassSymbol)sym;
+ if (!toolEnv.isSynthetic(s)) {
+ addAllClasses(list, s, filtered);
+ }
+ }
+ }
+ } catch (CompletionFailure e) {
+ // quietly ignore completion failures
+ }
+ }
+
+ /**
+ * Returns a list of all classes contained in this package, including
+ * member classes of those classes, and their member classes, etc.
+ */
+ private void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
+ boolean filtered = true;
+ PackageSymbol sym = (PackageSymbol)pkg;
+ for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
+ if (isym != null) {
+ ClassSymbol s = (ClassSymbol)isym;
+ if (!toolEnv.isSynthetic(sym)) {
+ addAllClasses(list, s, filtered);
+ }
+ }
+ }
+ }
+
+ SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
+ /**
+ * Returns whether an element ought to be documented.
+ * @param e the element in question
+ * @return true if the element should be documented
+ */
+ public boolean shouldDocument(Element e) {
+ if (shouldDocumentVisitor == null) {
+ shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ return shouldDocument((ClassSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitVariable(VariableElement e, Void p) {
+ return shouldDocument((VarSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitExecutable(ExecutableElement e, Void p) {
+ return shouldDocument((MethodSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ return accessFilter.checkModifier(e);
+ }
+ };
+ }
+ return shouldDocumentVisitor.visit(e);
+ }
+
+ /** Check whether this member should be documented. */
+ private boolean shouldDocument(VarSymbol sym) {
+ if (toolEnv.isSynthetic(sym)) {
+ return false;
+ }
+ return accessFilter.checkModifier(sym);
+ }
+
+ /** Check whether this member should be documented. */
+ private boolean shouldDocument(MethodSymbol sym) {
+ if (toolEnv.isSynthetic(sym)) {
+ return false;
+ }
+ return accessFilter.checkModifier(sym);
+ }
+
+ /** Check whether this class should be documented. */
+ private boolean shouldDocument(ClassSymbol sym) {
+ return
+ !toolEnv.isSynthetic(sym) && // no synthetics
+ (xclasses || toolEnv.hasPath(sym)) &&
+ isVisible(sym);
+ }
+
+ /**
+ * Returns the visibility of a type element.
+ * If the type element is a nested type, then check if the
+ * enclosing is static or the enclosed is visible.
+ *
+ * @param te the type element to be checked
+ * @return true if the element is visible
+ */
+ public boolean isVisible(TypeElement te) {
+ ClassSymbol sym = (ClassSymbol)te;
+ if (!accessFilter.checkModifier(sym)) {
+ return false;
+ }
+ ClassSymbol encl = sym.owner.enclClass();
+ return (encl == null || (sym.flags_field & Flags.STATIC) != 0 || isVisible(encl));
+ }
+
+ private class IncludedVisitor extends SimpleElementVisitor9<Boolean, Void> {
+
+ final private Set<Element> includedCache;
+
+ public IncludedVisitor() {
+ includedCache = new LinkedHashSet<>();
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitModule(ModuleElement e, Void p) {
+ // deduced by specified and/or requires expansion
+ return includedModuleElements.contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ // deduced by specified or downward expansions
+ return includedPackageElements.contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ if (includedTypeElements.contains(e)) {
+ return true;
+ }
+ if (shouldDocument(e)) {
+ // Class is nameable from top-level and
+ // the class and all enclosing classes
+ // pass the modifier filter.
+ PackageElement pkg = toolEnv.elements.getPackageOf(e);
+ if (specifiedPackageElements.contains(pkg)) {
+ return true;
+ }
+ Element enclosing = e.getEnclosingElement();
+ if (enclosing != null) {
+ switch(enclosing.getKind()) {
+ case PACKAGE:
+ return specifiedPackageElements.contains((PackageElement)enclosing);
+ case CLASS: case INTERFACE: case ENUM: case ANNOTATION_TYPE:
+ return visit((TypeElement) enclosing);
+ default:
+ throw new AssertionError("unknown element: " + enclosing);
+ }
+ }
+ }
+ return false;
+ }
+
+ // members
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean defaultAction(Element e, Void p) {
+ if (includedCache.contains(e))
+ return true;
+ if (visit(e.getEnclosingElement()) && shouldDocument(e)) {
+ switch(e.getKind()) {
+ case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
+ case MODULE: case OTHER: case PACKAGE:
+ throw new AssertionError("invalid element for this operation: " + e);
+ default:
+ // the only allowed kinds in the cache are "members"
+ includedCache.add(e);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitUnknown(Element e, Void p) {
+ throw new AssertionError("unknown element: " + e);
+ }
+
+ }
+
+ class Entry {
+ final ModulePackage modpkg;
+ Boolean excluded = false;
+ com.sun.tools.javac.util.List<JavaFileObject> files;
+
+ Entry(ModulePackage modpkg) {
+ this.modpkg = modpkg;
+ }
+
+ Entry(String name) {
+ modpkg = new ModulePackage(name);
+ }
+
+ boolean isExcluded() {
+ return excluded;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry{" + "modpkg=" + modpkg + ", excluded=" + excluded + ", files=" + files + '}';
+ }
+ }
+
+ /**
+ * A container class to retrieve the module and package pair
+ * from a parsed qualified package name.
+ */
+ static class ModulePackage {
+
+ public final String moduleName;
+ public final String packageName;
+
+ ModulePackage(String modulename, String packagename) {
+ this.moduleName = modulename;
+ this.packageName = packagename;
+ }
+
+ ModulePackage(ModuleElement msym, String packagename) {
+ this.moduleName = msym.toString();
+ this.packageName = packagename;
+ }
+
+ ModulePackage(String name) {
+ String a[] = name.split("/");
+ if (a.length == 2) {
+ this.moduleName = a[0];
+ this.packageName = a[1];
+ } else {
+ moduleName = null;
+ packageName = name;
+ }
+ }
+
+ boolean hasModule() {
+ return this.moduleName != null;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ModulePackage) {
+ ModulePackage that = (ModulePackage)obj;
+ return this.toString().equals(that.toString());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return moduleName == null ? packageName : moduleName + "/" + packageName;
+ }
+ }
+
+ /**
+ * A class which filters the access flags on classes, fields, methods, etc.
+ *
+ * @see javax.lang.model.element.Modifier
+ */
+
+ static class ModifierFilter {
+ /**
+ * The allowed ElementKind that can be stored.
+ */
+ static final EnumSet<ElementKind> ALLOWED_KINDS = EnumSet.of(ElementKind.METHOD,
+ ElementKind.CLASS,
+ ElementKind.PACKAGE,
+ ElementKind.MODULE);
+
+ // all possible accesss levels allowed for each element
+ private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
+ new EnumMap<>(ElementKind.class);
+
+ // the specified access level for each element
+ private final EnumMap<ElementKind, AccessKind> accessMap =
+ new EnumMap<>(ElementKind.class);
+
+ /**
+ * Constructor - Specify a filter.
+ *
+ * @param accessSet an Access filter.
+ */
+ ModifierFilter(Map<ToolOption, Object> opts) {
+
+ AccessKind accessValue = null;
+ for (ElementKind kind : ALLOWED_KINDS) {
+ switch (kind) {
+ case METHOD:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_MEMBERS);
+ break;
+ case CLASS:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_TYPES);
+ break;
+ case PACKAGE:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_PACKAGES);
+ break;
+ case MODULE:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_MODULE_CONTENTS);
+ break;
+ default:
+ throw new AssertionError("unknown element: " + kind);
+
+ }
+ accessMap.put(kind, accessValue);
+ filterMap.put(kind, getFilterSet(accessValue));
+ }
+ }
+
+ static EnumSet<AccessKind> getFilterSet(AccessKind acccessValue) {
+ switch (acccessValue) {
+ case PUBLIC:
+ return EnumSet.of(AccessKind.PUBLIC);
+ case PROTECTED:
+ default:
+ return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED);
+ case PACKAGE:
+ return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED, AccessKind.PACKAGE);
+ case PRIVATE:
+ return EnumSet.allOf(AccessKind.class);
+ }
+ }
+
+ public AccessKind getAccessValue(ElementKind kind) {
+ if (!ALLOWED_KINDS.contains(kind)) {
+ throw new IllegalArgumentException("not allowed: " + kind);
+ }
+ return accessMap.getOrDefault(kind, AccessKind.PROTECTED);
+ }
+
+ /**
+ * Returns true if access is allowed.
+ *
+ * @param e the element in question
+ * @return whether the modifiers pass this filter
+ */
+ public boolean checkModifier(Element e) {
+ Set<Modifier> modifiers = e.getModifiers();
+ AccessKind fflag = AccessKind.PACKAGE;
+ if (modifiers.contains(Modifier.PUBLIC)) {
+ fflag = AccessKind.PUBLIC;
+ } else if (modifiers.contains(Modifier.PROTECTED)) {
+ fflag = AccessKind.PROTECTED;
+ } else if (modifiers.contains(Modifier.PRIVATE)) {
+ fflag = AccessKind.PRIVATE;
+ }
+ EnumSet<AccessKind> filterSet = filterMap.get(getAllowedKind(e.getKind()));
+ return filterSet.contains(fflag);
+ }
+
+ // convert a requested element kind to an allowed access kind
+ private ElementKind getAllowedKind(ElementKind kind) {
+ switch (kind) {
+ case CLASS: case METHOD: case MODULE: case PACKAGE:
+ return kind;
+ case ANNOTATION_TYPE: case ENUM: case INTERFACE:
+ return ElementKind.CLASS;
+ case CONSTRUCTOR: case ENUM_CONSTANT: case EXCEPTION_PARAMETER:
+ case FIELD: case INSTANCE_INIT: case LOCAL_VARIABLE: case PARAMETER:
+ case RESOURCE_VARIABLE: case STATIC_INIT: case TYPE_PARAMETER:
+ return ElementKind.METHOD;
+ default:
+ throw new AssertionError("unsupported kind: " + kind);
+ }
+ }
+ } // end ModifierFilter
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,27 +29,18 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@@ -57,11 +48,9 @@
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Position;
import jdk.javadoc.doclet.DocletEnvironment;
-
/**
* This class could be the main entry point for Javadoc when Javadoc is used as a
* component in a larger software system. It provides operations to
@@ -131,44 +120,41 @@
}
}
- public DocletEnvironment getEnvironment(String encoding,
- String showAccess,
- String overviewpath,
- List<String> args,
- Iterable<? extends JavaFileObject> fileObjects,
- List<String> subPackages,
- List<String> excludedPackages,
- boolean docClasses,
- boolean quiet) throws IOException {
+ public DocletEnvironment getEnvironment(Map<ToolOption, Object> jdtoolOpts,
+ List<String> javaNames,
+ Iterable<? extends JavaFileObject> fileObjects) throws IOException {
toolEnv = ToolEnvironment.instance(context);
- toolEnv.intialize(encoding, showAccess, overviewpath, args, fileObjects,
- subPackages, excludedPackages, docClasses, quiet);
-
- javadocFinder.sourceCompleter = docClasses ? Completer.NULL_COMPLETER : sourceCompleter;
+ toolEnv.initialize(jdtoolOpts);
+ ElementsTable etable = new ElementsTable(context, jdtoolOpts);
+ javadocFinder.sourceCompleter = etable.xclasses
+ ? Completer.NULL_COMPLETER
+ : sourceCompleter;
- if (docClasses) {
- // If -Xclasses is set, the args should be a series of class names
- for (String arg: args) {
+ if (etable.xclasses) {
+ // If -Xclasses is set, the args should be a list of class names
+ for (String arg: javaNames) {
if (!isValidPackageName(arg)) // checks
- toolEnv.error(null, "main.illegal_class_name", arg);
+ toolEnv.error("main.illegal_class_name", arg);
}
if (messager.nerrors() != 0) {
return null;
}
- return new DocEnvImpl(toolEnv, args);
+ etable.setClassArgList(javaNames);
+ // prepare, force the data structures to be analyzed
+ etable.analyze();
+ return new DocEnvImpl(toolEnv, etable);
}
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();
- Set<String> includedPackages = new LinkedHashSet<>();
try {
-
StandardJavaFileManager fm = toolEnv.fileManager instanceof StandardJavaFileManager
- ? (StandardJavaFileManager) toolEnv.fileManager : null;
+ ? (StandardJavaFileManager) toolEnv.fileManager
+ : null;
Set<String> packageNames = new LinkedHashSet<>();
// Normally, the args should be a series of package names or file names.
// Parse the files and collect the package names.
- for (String arg: args) {
+ for (String arg: javaNames) {
if (fm != null && arg.endsWith(".java") && new File(arg).exists()) {
if (new File(arg).getName().equals("module-info.java")) {
toolEnv.warning("main.file_ignored", arg);
@@ -181,37 +167,22 @@
if (fm == null)
throw new IllegalArgumentException();
else
- toolEnv.error(null, "main.file_not_found", arg);
+ toolEnv.error("main.file_not_found", arg);
} else {
- toolEnv.error(null, "main.illegal_package_name", arg);
+ toolEnv.error("main.illegal_package_name", arg);
}
}
// Parse file objects provide via the DocumentationTool API
parse(fileObjects, classTrees, true);
- modules.initModules(classTrees.toList());
-
- // Build up the complete list of any packages to be documented
- Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH
- : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH) ? StandardLocation.SOURCE_PATH
- : StandardLocation.CLASS_PATH;
-
- PackageTable t = new PackageTable(toolEnv.fileManager, location)
- .packages(packageNames)
- .subpackages(subPackages, excludedPackages);
+ etable.packages(packageNames)
+ .classTrees(classTrees.toList())
+ .scanSpecifiedItems();
- includedPackages = t.getIncludedPackages();
-
- // Parse the files in the packages to be documented
+ // Parse the files in the packages and subpackages to be documented
ListBuffer<JCCompilationUnit> packageTrees = new ListBuffer<>();
- for (String packageName: includedPackages) {
- List<JavaFileObject> files = t.getFiles(packageName);
- toolEnv.notice("main.Loading_source_files_for_package", packageName);
- if (files.isEmpty())
- toolEnv.warning("main.no_source_files_for_package", packageName);
- parse(files, packageTrees, false);
- }
+ parse(etable.getFilesToParse(), packageTrees, false);
modules.enter(packageTrees.toList(), null);
if (messager.nerrors() != 0) {
@@ -220,24 +191,40 @@
// Enter symbols for all files
toolEnv.notice("main.Building_tree");
- javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
+ javadocEnter.main(classTrees.toList().appendList(packageTrees));
+ etable.setClassDeclList(listClasses(classTrees.toList()));
enterDone = true;
+ etable.analyze();
+ } catch (CompletionFailure cf) {
+ toolEnv.printError(cf.getMessage());
} catch (Abort ex) {}
if (messager.nerrors() != 0)
return null;
- toolEnv.docEnv = new DocEnvImpl(toolEnv, listClasses(classTrees.toList()),
- new ArrayList<>(includedPackages));
+
+ toolEnv.docEnv = new DocEnvImpl(toolEnv, etable);
return toolEnv.docEnv;
}
/** Is the given string a valid package name? */
boolean isValidPackageName(String s) {
- int index;
- while ((index = s.indexOf('.')) != -1) {
- if (!isValidClassName(s.substring(0, index))) return false;
- s = s.substring(index+1);
+ if (s.contains("/")) {
+ String[] a = s.split("/");
+ if (a.length == 2) {
+ return isValidPackageName0(a[0]) && isValidPackageName0(a[1]);
+ }
+ return false;
+ }
+ return isValidPackageName0(s);
+ }
+
+ private boolean isValidPackageName0(String s) {
+ for (int index = s.indexOf('.') ; index != -1; index = s.indexOf('.')) {
+ if (!isValidClassName(s.substring(0, index))) {
+ return false;
+ }
+ s = s.substring(index + 1);
}
return isValidClassName(s);
}
@@ -253,8 +240,7 @@
}
}
- /** Are surrogates supported?
- */
+ /** Are surrogates supported? */
final static boolean surrogatesSupported = surrogatesSupported();
private static boolean surrogatesSupported() {
try {
@@ -279,7 +265,7 @@
int cp = s.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
return false;
- for (int j=Character.charCount(cp); j<s.length(); j+=Character.charCount(cp)) {
+ for (int j = Character.charCount(cp); j < s.length(); j += Character.charCount(cp)) {
cp = s.codePointAt(j);
if (!Character.isJavaIdentifierPart(cp))
return false;
@@ -287,7 +273,7 @@
} else {
if (!Character.isJavaIdentifierStart(s.charAt(0)))
return false;
- for (int j=1; j<s.length(); j++)
+ for (int j = 1; j < s.length(); j++)
if (!Character.isJavaIdentifierPart(s.charAt(j)))
return false;
}
@@ -307,141 +293,4 @@
}
return result;
}
-
- /**
- * A table to manage included and excluded packages.
- */
- class PackageTable {
- private final Map<String, Entry> entries = new LinkedHashMap<>();
- private final Set<String> includedPackages = new LinkedHashSet<>();
- private final JavaFileManager fm;
- private final Location location;
- private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
-
- /**
- * Creates a table to manage included and excluded packages.
- * @param fm The file manager used to locate source files
- * @param locn the location used to locate source files
- */
- PackageTable(JavaFileManager fm, Location locn) {
- this.fm = fm;
- this.location = locn;
- getEntry("").excluded = false;
- }
-
- PackageTable packages(Collection<String> packageNames) {
- includedPackages.addAll(packageNames);
- return this;
- }
-
- PackageTable subpackages(Collection<String> packageNames, Collection<String> excludePackageNames)
- throws IOException {
- for (String p: excludePackageNames) {
- getEntry(p).excluded = true;
- }
-
- for (String packageName: packageNames) {
- for (JavaFileObject fo: fm.list(location, packageName, sourceKinds, true)) {
- String binaryName = fm.inferBinaryName(location, fo);
- String pn = getPackageName(binaryName);
- String simpleName = getSimpleName(binaryName);
- Entry e = getEntry(pn);
- if (!e.isExcluded() && isValidClassName(simpleName)) {
- includedPackages.add(pn);
- e.files = (e.files == null
- ? com.sun.tools.javac.util.List.of(fo)
- : e.files.prepend(fo));
- }
- }
- }
- return this;
- }
-
- /**
- * Returns the aggregate set of included packages.
- * @return the aggregate set of included packages
- */
- Set<String> getIncludedPackages() {
- return includedPackages;
- }
-
- /**
- * Returns the set of source files for a package.
- * @param packageName the specified package
- * @return the set of file objects for the specified package
- * @throws IOException if an error occurs while accessing the files
- */
- List<JavaFileObject> getFiles(String packageName) throws IOException {
- Entry e = getEntry(packageName);
- // The files may have been found as a side effect of searching for subpackages
- if (e.files != null)
- return e.files;
-
- ListBuffer<JavaFileObject> lb = new ListBuffer<>();
- Location packageLocn = getLocation(packageName);
- if (packageLocn == null)
- return Collections.emptyList();
- for (JavaFileObject fo: fm.list(packageLocn, packageName, sourceKinds, false)) {
- String binaryName = fm.inferBinaryName(packageLocn, fo);
- String simpleName = getSimpleName(binaryName);
- if (isValidClassName(simpleName)) {
- lb.append(fo);
- }
- }
-
- return lb.toList();
- }
-
- private Location getLocation(String packageName) throws IOException {
- if (location == StandardLocation.MODULE_SOURCE_PATH) {
- // TODO: handle invalid results better.
- Name pack = names.fromString(packageName);
-
- for (ModuleSymbol msym : modules.allModules()) {
- PackageSymbol p = syms.getPackage(msym, pack);
- if (p != null && !p.members().isEmpty()) {
- return fm.getModuleLocation(location, msym.name.toString());
- }
- }
-
- return null;
- } else {
- return location;
- }
- }
-
- private Entry getEntry(String name) {
- Entry e = entries.get(name);
- if (e == null)
- entries.put(name, e = new Entry(name));
- return e;
- }
-
- private String getPackageName(String name) {
- int lastDot = name.lastIndexOf(".");
- return (lastDot == -1 ? "" : name.substring(0, lastDot));
- }
-
- private String getSimpleName(String name) {
- int lastDot = name.lastIndexOf(".");
- return (lastDot == -1 ? name : name.substring(lastDot + 1));
- }
-
- class Entry {
- final String name;
- Boolean excluded;
- com.sun.tools.javac.util.List<JavaFileObject> files;
-
- Entry(String name) {
- this.name = name;
- }
-
- boolean isExcluded() {
- if (excluded == null)
- excluded = getEntry(getPackageName(name)).isExcluded();
- return excluded;
- }
- }
- }
-
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Mon Aug 29 08:53:32 2016 -0700
@@ -29,7 +29,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
-import java.lang.reflect.Method;
import java.nio.file.Path;
import java.text.BreakIterator;
import java.util.ArrayList;
@@ -41,8 +40,6 @@
import java.util.Objects;
import java.util.Set;
-import static javax.tools.DocumentationTool.Location.*;
-
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
@@ -65,6 +62,8 @@
import jdk.javadoc.doclet.Doclet.Option;
import jdk.javadoc.doclet.DocletEnvironment;
+import static javax.tools.DocumentationTool.Location.*;
+
import static com.sun.tools.javac.main.Option.*;
/**
@@ -92,9 +91,6 @@
private static final String ProgramName = "javadoc";
- // meaning we allow all visibility of PROTECTED and PUBLIC
- private static final String defaultModifier = "protected";
-
private Messager messager;
private final String docletName;
@@ -337,6 +333,7 @@
/**
* Main program - internal
*/
+ @SuppressWarnings("unchecked")
private boolean parseAndExecute(List<String> argList,
Iterable<? extends JavaFileObject> fileObjects) throws IOException {
long tm = System.currentTimeMillis();
@@ -390,28 +387,25 @@
}
compOpts.notifyListeners();
+ List<String> modules = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.MODULE,
+ s -> Collections.EMPTY_LIST);
- if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
- usageError("main.No_packages_or_classes_specified");
+ if (modules.isEmpty()) {
+ List<String> subpkgs = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.SUBPACKAGES,
+ s -> Collections.EMPTY_LIST);
+ if (subpkgs.isEmpty()) {
+ if (javaNames.isEmpty() && isEmpty(fileObjects)) {
+ usageError("main.No_modules_packages_or_classes_specified");
+ }
+ }
}
JavadocTool comp = JavadocTool.make0(context);
if (comp == null) return false;
- if (showAccess == null) {
- setFilter(defaultModifier);
- }
-
- DocletEnvironment root = comp.getEnvironment(
- encoding,
- showAccess,
- overviewpath,
+ DocletEnvironment docEnv = comp.getEnvironment(jdtoolOpts,
javaNames,
- fileObjects,
- subPackages,
- excludedPackages,
- docClasses,
- quiet);
+ fileObjects);
// release resources
comp = null;
@@ -421,8 +415,8 @@
trees.setBreakIterator(BreakIterator.getSentenceInstance(locale));
}
// pass off control to the doclet
- boolean ok = root != null;
- if (ok) ok = doclet.run(root);
+ boolean ok = docEnv != null;
+ if (ok) ok = doclet.run(docEnv);
// We're done.
if (compOpts.get("-verbose") != null) {
@@ -470,11 +464,11 @@
for (int i = 0 ; i < argv.size() ; i++) {
String arg = argv.get(i);
if (arg.equals(ToolOption.LOCALE.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
String lname = argv.get(i);
locale = getLocale(lname);
} else if (arg.equals(ToolOption.DOCLET.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
if (userDocletName != null) {
usageError("main.more_than_one_doclet_specified_0_and_1",
userDocletName, argv.get(i));
@@ -485,7 +479,7 @@
}
userDocletName = argv.get(i);
} else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
if (userDocletPath == null) {
userDocletPath = argv.get(i);
} else {
@@ -605,12 +599,11 @@
handleDocletOptions(i, args, true);
if (o.hasArg) {
- oneArg(args, i++);
+ checkOneArg(args, i++);
o.process(this, args.get(i));
} else if (o.hasSuffix) {
o.process(this, arg);
} else {
- setOption(arg);
o.process(this);
}
} else if (arg.startsWith("-XD")) {
@@ -633,13 +626,11 @@
}
/**
- * Set one arg option.
+ * Check the one arg option.
* Error and exit if one argument is not provided.
*/
- private void oneArg(List<String> args, int index) {
- if ((index + 1) < args.size()) {
- setOption(args.get(index), args.get(index+1));
- } else {
+ private void checkOneArg(List<String> args, int index) {
+ if ((index + 1) >= args.size() || args.get(index + 1).startsWith("-d")) {
usageError("main.requires_argument", args.get(index));
}
}
@@ -659,32 +650,6 @@
}
/**
- * indicate an option with no arguments was given.
- */
- private void setOption(String opt) {
- String[] option = { opt };
- options.add(Arrays.asList(option));
- }
-
- /**
- * indicate an option with one argument was given.
- */
- private void setOption(String opt, String argument) {
- String[] option = { opt, argument };
- options.add(Arrays.asList(option));
- }
-
- /**
- * indicate an option with the specified list of arguments was given.
- */
- private void setOption(String opt, List<String> arguments) {
- List<String> args = new ArrayList<>(arguments.size() + 1);
- args.add(opt);
- args.addAll(arguments);
- options.add(args);
- }
-
- /**
* Get the locale if specified on the command line
* else return null and if locale option is not used
* then return default locale.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,16 +26,12 @@
package jdk.javadoc.internal.tool;
-import java.lang.reflect.Modifier;
import java.util.*;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleElementVisitor9;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -44,15 +40,11 @@
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Check;
@@ -67,13 +59,9 @@
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert;
-import com.sun.tools.javac.util.DefinedBy;
-import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
-import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
-
/**
* Holds the environment for a run of javadoc.
* Holds only the information needed throughout the
@@ -113,14 +101,8 @@
/** The name table. */
private Names names;
- /** The encoding name. */
- private String encoding;
-
final Symbol externalizableSym;
- /** Access filter (public, protected, ...). */
- protected ModifierFilter filter;
-
/**
* True if we do not want to print any notifications at all.
*/
@@ -181,20 +163,8 @@
elementToTreePath = new HashMap<>();
}
- public void intialize(String encoding,
- String showAccess,
- String overviewpath,
- List<String> javaNames,
- Iterable<? extends JavaFileObject> fileObjects,
- List<String> subPackages,
- List<String> excludedPackages,
- boolean docClasses,
- boolean quiet) {
- this.filter = ModifierFilter.getModifierFilter(showAccess);
- this.quiet = quiet;
-
- this.setEncoding(encoding);
- this.docClasses = docClasses;
+ public void initialize(Map<ToolOption, Object> toolOpts) {
+ this.quiet = (boolean)toolOpts.getOrDefault(ToolOption.QUIET, false);
}
/**
@@ -212,54 +182,8 @@
}
}
- private boolean isSynthetic(long flags) {
- return (flags & Flags.SYNTHETIC) != 0;
- }
-
- private boolean isSynthetic(Symbol sym) {
- return isSynthetic(sym.flags_field);
- }
-
- SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
- public boolean shouldDocument(Element e) {
- if (shouldDocumentVisitor == null) {
- shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitType(TypeElement e, Void p) {
- return shouldDocument((ClassSymbol)e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitVariable(VariableElement e, Void p) {
- return shouldDocument((VarSymbol)e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitExecutable(ExecutableElement e, Void p) {
- return shouldDocument((MethodSymbol)e);
- }
- };
- }
- return shouldDocumentVisitor.visit(e);
- }
-
- /** Check whether this member should be documented. */
- public boolean shouldDocument(VarSymbol sym) {
- long mod = sym.flags();
- if (isSynthetic(mod)) {
- return false;
- }
- return filter.checkModifier(translateModifiers(mod));
- }
-
- /** Check whether this member should be documented. */
- public boolean shouldDocument(MethodSymbol sym) {
- long mod = sym.flags();
- if (isSynthetic(mod)) {
- return false;
- }
- return filter.checkModifier(translateModifiers(mod));
+ boolean isSynthetic(Symbol sym) {
+ return (sym.flags() & Flags.SYNTHETIC) != 0;
}
void setElementToTreePath(Element e, TreePath tree) {
@@ -268,43 +192,16 @@
elementToTreePath.put(e, tree);
}
- private boolean hasLeaf(ClassSymbol sym) {
+ /**
+ * Returns true if the symbol has a tree path associated with it.
+ * Primarily used to disambiguate a symbol associated with a source
+ * file versus a class file.
+ * @param sym the symbol to be checked
+ * @return true if the symbol has a tree path
+ */
+ boolean hasPath(ClassSymbol sym) {
TreePath path = elementToTreePath.get(sym);
- if (path == null)
- return false;
- return path.getLeaf() != null;
- }
-
- /** check whether this class should be documented. */
- public boolean shouldDocument(ClassSymbol sym) {
- return
- !isSynthetic(sym.flags_field) && // no synthetics
- (docClasses || hasLeaf(sym)) &&
- isVisible(sym);
- }
-
- //### Comment below is inaccurate wrt modifier filter testing
- /**
- * Check the visibility if this is an nested class.
- * if this is not a nested class, return true.
- * if this is an static visible nested class,
- * return true.
- * if this is an visible nested class
- * if the outer class is visible return true.
- * else return false.
- * IMPORTANT: This also allows, static nested classes
- * to be defined inside an nested class, which is not
- * allowed by the compiler. So such an test case will
- * not reach upto this method itself, but if compiler
- * allows it, then that will go through.
- */
- public boolean isVisible(ClassSymbol sym) {
- long mod = sym.flags_field;
- if (!filter.checkModifier(translateModifiers(mod))) {
- return false;
- }
- ClassSymbol encl = sym.owner.enclClass();
- return (encl == null || (mod & Flags.STATIC) != 0 || isVisible(encl));
+ return path != null;
}
//---------------- print forwarders ----------------//
@@ -366,6 +263,15 @@
/**
* Print error message, increment error count.
+ * @param key selects message from resource
+ * @param args replacement arguments
+ */
+ public void error(String key, String... args) {
+ error(null, key, args);
+ }
+
+ /**
+ * Print error message, increment error count.
*
* @param element the source element
* @param key selects message from resource
@@ -553,48 +459,6 @@
throw new Messager.ExitJavadoc();
}
- /**
- * Adds all inner classes of this class, and their inner classes recursively, to the list
- */
- void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
- ClassSymbol klass = (ClassSymbol)typeElement;
- try {
- if (isSynthetic(klass.flags())) return;
- // sometimes synthetic classes are not marked synthetic
- if (!JavadocTool.isValidClassName(klass.name.toString())) return;
- if (filtered && !shouldDocument(klass)) return;
- if (list.contains(klass)) return;
- list.add(klass);
- for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
- if (sym != null && sym.kind == Kind.TYP) {
- ClassSymbol s = (ClassSymbol)sym;
- if (!isSynthetic(s.flags())) {
- addAllClasses(list, s, filtered);
- }
- }
- }
- } catch (CompletionFailure e) {
- // quietly ignore completion failures
- }
- }
-
- /**
- * Return a list of all classes contained in this package, including
- * member classes of those classes, and their member classes, etc.
- */
- void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
- boolean filtered = true;
- PackageSymbol sym = (PackageSymbol)pkg;
- for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
- if (isym != null) {
- ClassSymbol s = (ClassSymbol)isym;
- if (!isSynthetic(s)) {
- addAllClasses(list, s, filtered);
- }
- }
- }
- }
-
TreePath getTreePath(JCCompilationUnit tree) {
TreePath p = treePaths.get(tree);
if (p == null)
@@ -624,225 +488,11 @@
return types;
}
- /**
- * Set the encoding.
- */
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
public Env<AttrContext> getEnv(ClassSymbol tsym) {
return enter.getEnv(tsym);
}
- /**
- * Get the encoding.
- */
- public String getEncoding() {
- return encoding;
- }
-
- /**
- * Convert modifier bits from private coding used by
- * the compiler to that of java.lang.reflect.Modifier.
- */
- static int translateModifiers(long flags) {
- int result = 0;
- if ((flags & Flags.ABSTRACT) != 0)
- result |= Modifier.ABSTRACT;
- if ((flags & Flags.FINAL) != 0)
- result |= Modifier.FINAL;
- if ((flags & Flags.INTERFACE) != 0)
- result |= Modifier.INTERFACE;
- if ((flags & Flags.NATIVE) != 0)
- result |= Modifier.NATIVE;
- if ((flags & Flags.PRIVATE) != 0)
- result |= Modifier.PRIVATE;
- if ((flags & Flags.PROTECTED) != 0)
- result |= Modifier.PROTECTED;
- if ((flags & Flags.PUBLIC) != 0)
- result |= Modifier.PUBLIC;
- if ((flags & Flags.STATIC) != 0)
- result |= Modifier.STATIC;
- if ((flags & Flags.SYNCHRONIZED) != 0)
- result |= Modifier.SYNCHRONIZED;
- if ((flags & Flags.TRANSIENT) != 0)
- result |= Modifier.TRANSIENT;
- if ((flags & Flags.VOLATILE) != 0)
- result |= Modifier.VOLATILE;
- return result;
- }
-
- private final Set<Element> includedSet = new HashSet<>();
-
- public void setIncluded(Element element) {
- includedSet.add(element);
- }
-
- private SimpleElementVisitor9<Boolean, Void> includedVisitor = null;
-
- public boolean isIncluded(Element e) {
- if (e == null) {
- return false;
- }
- if (includedVisitor == null) {
- includedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitType(TypeElement e, Void p) {
- if (includedSet.contains(e)) {
- return true;
- }
- if (shouldDocument(e)) {
- // Class is nameable from top-level and
- // the class and all enclosing classes
- // pass the modifier filter.
- PackageElement pkg = elements.getPackageOf(e);
- if (includedSet.contains(pkg)) {
- setIncluded(e);
- return true;
- }
- Element enclosing = e.getEnclosingElement();
- if (enclosing != null && includedSet.contains(enclosing)) {
- setIncluded(e);
- return true;
- }
- }
- return false;
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitPackage(PackageElement e, Void p) {
- return includedSet.contains(e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitUnknown(Element e, Void p) {
- throw new AssertionError("unknown element: " + e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean defaultAction(Element e, Void p) {
- return visit(e.getEnclosingElement()) && shouldDocument(e);
- }
- };
- }
- return includedVisitor.visit(e);
- }
-
public boolean isQuiet() {
return quiet;
}
-
- /**
- * A class which filters the access flags on classes, fields, methods, etc.
- *
- * <p>
- * <b>This is NOT part of any supported API. If you write code that depends on this, you do so
- * at your own risk. This code and its internal interfaces are subject to change or deletion
- * without notice.</b>
- *
- * @see javax.lang.model.element.Modifier
- * @author Robert Field
- */
-
- private static class ModifierFilter {
-
- static enum FilterFlag {
- PACKAGE,
- PRIVATE,
- PROTECTED,
- PUBLIC
- }
-
- private Set<FilterFlag> oneOf;
-
- /**
- * Constructor - Specify a filter.
- *
- * @param oneOf a set containing desired flags to be matched.
- */
- ModifierFilter(Set<FilterFlag> oneOf) {
- this.oneOf = oneOf;
- }
-
- /**
- * Constructor - Specify a filter.
- *
- * @param oneOf an array containing desired flags to be matched.
- */
- ModifierFilter(FilterFlag... oneOf) {
- this.oneOf = new HashSet<>();
- this.oneOf.addAll(Arrays.asList(oneOf));
- }
-
- static ModifierFilter getModifierFilter(String showAccess) {
- switch (showAccess) {
- case "public":
- return new ModifierFilter(FilterFlag.PUBLIC);
- case "package":
- return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED,
- FilterFlag.PACKAGE);
- case "private":
- return new ModifierFilter(FilterFlag.PRIVATE);
- default:
- return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED);
- }
- }
-
- private boolean hasFlag(long flag, long modifierBits) {
- return (flag & modifierBits) != 0;
- }
-
- private List<FilterFlag> flagsToModifiers(long modifierBits) {
- List<FilterFlag> list = new ArrayList<>();
- boolean isPackage = true;
- if (hasFlag(com.sun.tools.javac.code.Flags.PRIVATE, modifierBits)) {
- list.add(FilterFlag.PRIVATE);
- isPackage = false;
- }
- if (hasFlag(com.sun.tools.javac.code.Flags.PROTECTED, modifierBits)) {
- list.add(FilterFlag.PROTECTED);
- isPackage = false;
- }
- if (hasFlag(com.sun.tools.javac.code.Flags.PUBLIC, modifierBits)) {
- list.add(FilterFlag.PUBLIC);
- isPackage = false;
- }
- if (isPackage) {
- list.add(FilterFlag.PACKAGE);
- }
- return list;
- }
-
- /**
- * Filter on modifier bits.
- *
- * @param modifierBits Bits as specified in the Modifier class
- *
- * @return Whether the modifierBits pass this filter.
- */
- public boolean checkModifier(int modifierBits) {
- return checkModifier(flagsToModifiers(modifierBits));
- }
-
- /**
- * Filter on Filter flags
- *
- * @param modifiers Flags as specified in the FilterFlags enumeration.
- *
- * @return if the modifier is contained.
- */
- public boolean checkModifier(List<FilterFlag> modifiers) {
- if (oneOf.contains(FilterFlag.PRIVATE)) {
- return true;
- }
- for (FilterFlag mod : modifiers) {
- if (oneOf.contains(mod)) {
- return true;
- }
- }
- return false;
- }
-
- } // end ModifierFilter
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Mon Aug 29 08:53:32 2016 -0700
@@ -26,10 +26,13 @@
package jdk.javadoc.internal.tool;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
+
+import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.OptionHelper;
@@ -44,6 +47,7 @@
* deletion without notice.</b>
*/
public enum ToolOption {
+
// ----- options for underlying compiler -----
BOOTCLASSPATH("-bootclasspath", true) {
@@ -193,10 +197,16 @@
}
},
+ MODULE("--module", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.addToList(this, ",", arg);
+ }
+ },
+
ENCODING("-encoding", true) {
@Override
public void process(Helper helper, String arg) {
- helper.encoding = arg;
helper.setFileManagerOpt(Option.ENCODING, arg);
}
},
@@ -296,14 +306,14 @@
SUBPACKAGES("-subpackages", true) {
@Override
public void process(Helper helper, String arg) {
- helper.addToList(helper.subPackages, arg);
+ helper.addToList(this, ":", arg);
}
},
EXCLUDE("-exclude", true) {
@Override
public void process(Helper helper, String arg) {
- helper.addToList(helper.excludedPackages, arg);
+ helper.addToList(this, ":", arg);
}
},
@@ -312,28 +322,63 @@
PACKAGE("-package") {
@Override
public void process(Helper helper) {
- helper.setFilter("package");
+ helper.setSimpleFilter("package");
}
},
PRIVATE("-private") {
@Override
public void process(Helper helper) {
- helper.setFilter("private");
+ helper.setSimpleFilter("private");
}
},
PROTECTED("-protected") {
@Override
public void process(Helper helper) {
- helper.setFilter("protected");
+ helper.setSimpleFilter("protected");
}
},
PUBLIC("-public") {
@Override
public void process(Helper helper) {
- helper.setFilter("public");
+ helper.setSimpleFilter("public");
+ }
+ },
+
+ SHOW_MEMBERS("--show-members:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setFilter(this, arg);
+ }
+ },
+
+ SHOW_TYPES("--show-types:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setFilter(this, arg);
+ }
+ },
+
+ SHOW_PACKAGES("--show-packages:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
+ }
+ },
+
+ SHOW_MODULE_CONTENTS("--show-module-contents:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
+ }
+ },
+
+ EXPAND_REQUIRES("--expand-requires:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
}
},
@@ -350,7 +395,7 @@
QUIET("-quiet") {
@Override
public void process(Helper helper) {
- helper.quiet = true;
+ helper.jdtoolOpts.put(QUIET, true);
}
},
@@ -385,19 +430,10 @@
}
},
- // the doclet consumes this
- OVERVIEW("-overview", true) {
- @Override
- public void process(Helper helper, String arg) {
- helper.setOverviewpath(arg);
- }
- },
-
XCLASSES("-Xclasses") {
@Override
public void process(Helper helper) {
- helper.docClasses = true;
-
+ helper.jdtoolOpts.put(XCLASSES, true);
}
},
@@ -452,14 +488,6 @@
}
static abstract class Helper {
- /** List of decoded options. */
- final List<List<String>> options = new ArrayList<>();
-
- /** Selected packages, from -subpackages. */
- final List<String> subPackages = new ArrayList<>();
-
- /** Excluded packages, from -exclude. */
- final List<String> excludedPackages = new ArrayList<>();
// File manager options
final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
@@ -467,18 +495,12 @@
/** javac options, set by various options. */
Options compOpts; // = Options.instance(context)
- /* Encoding for javac, and files written? set by -encoding. */
- String encoding = null;
+ /** Javadoc tool options */
+ final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
/** Set by -breakiterator. */
boolean breakiterator = false;
- /** Set by -quiet. */
- boolean quiet = false;
-
- /** Set by -Xclasses. */
- boolean docClasses = false;
-
/** Set by -Xwerror. */
boolean rejectWarnings = false;
@@ -488,9 +510,9 @@
/** Set by -locale. */
String docLocale = "";
- /** Set by -public, private, -protected, -package. */
- String showAccess = null;
- String overviewpath;
+ Helper() {
+ populateDefaultAccessMap();
+ }
abstract void usage();
abstract void Xusage();
@@ -498,33 +520,129 @@
abstract void usageError(String msg, Object... args);
abstract OptionHelper getOptionHelper();
- void addToList(List<String> list, String str){
- StringTokenizer st = new StringTokenizer(str, ":");
- String current;
- while(st.hasMoreTokens()){
- current = st.nextToken();
- list.add(current);
+ @SuppressWarnings("unchecked")
+ void addToList(ToolOption opt, String delimiter, String str) {
+ List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>());
+ list.addAll(Arrays.asList(str.split(delimiter)));
+ jdtoolOpts.put(opt, list);
+ }
+
+ String getOptionArgumentValue(String in) {
+ String[] values = in.trim().split(":");
+ return values[1];
+ }
+
+ void setExpandRequires(ToolOption opt, String arg) {
+ switch (arg) {
+ case "public":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
}
}
- void setFilter(String showAccess) {
- if (showAccess != null) {
- if (!"public".equals(showAccess)
- && !"protected".equals(showAccess)
- && !"private".equals(showAccess)
- && !"package".equals(showAccess)) {
- usageError("main.incompatible.access.flags");
- }
- this.showAccess = showAccess;
+ void setShowModuleContents(ToolOption opt, String arg) {
+ switch (arg) {
+ case "api":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
}
}
+ void setShowPackageAccess(ToolOption opt, String arg) {
+ switch (arg) {
+ case "exported":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
+ }
+ }
+
+
+ void setFilter(ToolOption opt, String arg) {
+ jdtoolOpts.put(opt, getAccessValue(arg));
+ }
+
+ void setSimpleFilter(String arg) {
+ handleSimpleOption(arg);
+ }
+
void setFileManagerOpt(Option opt, String arg) {
fileManagerOpts.put(opt, arg);
}
- private void setOverviewpath(String arg) {
- this.overviewpath = arg;
+ void handleSimpleOption(String arg) {
+ populateSimpleAccessMap(getAccessValue(arg));
+ }
+
+ /*
+ * This method handles both the simple options -package,
+ * -private, so on, in addition to the new ones such as
+ * --show-types:public and so on.
+ */
+ private AccessKind getAccessValue(String arg) {
+ int colon = arg.indexOf(':');
+ String value = (colon > 0)
+ ? arg.substring(colon + 1)
+ : arg;
+ switch (value) {
+ case "public":
+ return AccessKind.PUBLIC;
+ case "protected":
+ return AccessKind.PROTECTED;
+ case "package":
+ return AccessKind.PACKAGE;
+ case "private":
+ return AccessKind.PRIVATE;
+ default:
+ usageError("main.illegal_option_value", value);
+ return null;
+ }
+ }
+
+ /*
+ * Sets the entire kind map to PROTECTED this is the default.
+ */
+ private void populateDefaultAccessMap() {
+ populateSimpleAccessMap(AccessKind.PROTECTED);
+ }
+
+ /*
+ * This sets access to all the allowed kinds in the
+ * access map.
+ */
+ void populateSimpleAccessMap(AccessKind accessValue) {
+ for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
+ switch (kind) {
+ case METHOD:
+ jdtoolOpts.put(SHOW_MEMBERS, accessValue);
+ break;
+ case CLASS:
+ jdtoolOpts.put(SHOW_TYPES, accessValue);
+ break;
+ case PACKAGE:
+ jdtoolOpts.put(SHOW_PACKAGES, accessValue);
+ break;
+ case MODULE:
+ jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue);
+ break;
+ default:
+ throw new AssertionError("unknown element kind:" + kind);
+ }
+ }
}
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Mon Aug 29 08:53:32 2016 -0700
@@ -31,18 +31,53 @@
main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
\ -overview <file> Read overview documentation from HTML file\n\
\ -public Show only public classes and members\n\
-\ -protected Show protected/public classes and members (default)\n\
-\ -package Show package/protected/public classes and members\n\
+\ -protected Show protected/public classes and \n\
+\ members (default)\n\
+\ -package Show package/protected/public classes\n\
+\ and members\n\
\ -private Show all classes and members\n\
+\ --show-members:value Specifies which members (fields, methods\n\
+\ etc.) will be documented, where value can\n\
+\ be one of "public", "protected", "package"\n\
+\ or "private".\n\
+\ Default is protected, will show public and\n\
+\ protected members, "public" will show only\n\
+\ public members, "package" will show public,\n\
+\ protected and package members and \n\
+\ "private" will show all members\n\
+\ --show-types:value Specifies which types (classes, interfaces\n\
+\ etc.) will be documented, where value can be\n\
+\ one of "public", "protected", "package" or\n\
+\ "private".\n\
+\ Default is "protected", show public and\n\
+\ protected types, "package" will show public,\n\
+\ protected and package types and "private"\n\
+\ will show all types\n\
+\ --show-packages:value Specifies which module's packages will be\n\
+\ documented. Possible values are "exported"\n\
+\ or "all" packages\n\
+\ --show-module-contents:value Specifies the documentation granularity of\n\
+\ module declarations.\n\
+\ Possible values are "api" or "all".\n\
+\ --expand-requires:value Instructs the tool to expand the "requires"\n\
+\ module dependencies "public" expands all the\n\
+\ "requires public" edges of the module graph.\n\
+\ "all" expands all the "requires" edges of\n\
+\ the module graph by default only the\n\
+\ specified modules will be considered.\n\
\ -help Display command line options and exit\n\
+\ --module m1, m2.. Document the specified module(s)\n\
\ -doclet <class> Generate output via alternate doclet\n\
\ -docletpath <path> Specify where to find doclet class files\n\
-\ --module-source-path <path> Specify where to find input source files for multiple modules\n\
+\ --module-source-path <path> Specify where to find input source files\n\
+\ for multiple modules\n\
\ --upgrade-module-path <path> Override location of upgradeable modules\n\
\ --module-path <path>, -p <path> Specify where to find application modules\n\
\ --add-modules <module>(,<module>)*\n\
-\ Root modules to resolve in addition to the initial modules,\n\
-\ or all modules on the module path if <module> is ALL-MODULE-PATH.\n\
+\ Root modules to resolve in addition to the\n\
+\ initial modules,\n\
+\ or all modules on the module path if\n\
+\ <module> is ALL-MODULE-PATH.\n\
\ --limit-modules <module>(,<module>)*\n\
\ Limit the universe of observable modules\n\
\ --source-path <path> Specify where to find source files\n\
@@ -57,35 +92,40 @@
\ used for non-modular releases\n\
\ --system <jdk> Override location of system modules used\n\
\ for modular releases.\n\
-\ --release <release> Provide source compatibility with specified release\n\
-\ -source <release> Provide source compatibility with specified release\n\
+\ --release <release> Provide source compatibility with\n\
+\ specified release\n\
+\ -source <release> Provide source compatibility with\n\
+\ specified release\n\
\ -extdirs <dirlist> Override location of installed extensions\n\
\ -verbose Output messages about what Javadoc is doing\n\
\ -locale <name> Locale to be used, e.g. en_US or en_US_WIN\n\
\ -encoding <name> Source file encoding name\n\
\ -quiet Do not display status messages\n\
\ -J<flag> Pass <flag> directly to the runtime system\n\
-\ -X Print a synopsis of nonstandard options and exit\n
+\ -X Print a synopsis of nonstandard\n\
+\ options and exit\n
main.usage.foot=\n\
-GNU-style options may use '=' instead whitespace to separate the name of an option\n\
-from its value.\n
+GNU-style options may use '=' instead of whitespace to separate the name of an\n\
+option from its value.\n
main.Xusage=\
\ -Xmaxerrs <number> Set the maximum number of errors to print\n\
\ -Xmaxwarns <number> Set the maximum number of warnings to print\n\
\ --add-exports <module>/<package>=<other-module>(,<other-module>)*\n\
-\ Specify a package to be considered as exported from its \n\
-\ defining module to additional modules, or to all unnamed \n\
-\ modules if <other-module> is ALL-UNNAMED.\n\
+\ Specify a package to be considered as exported\n\
+\ from its defining module to additional modules,\n\
+\ or to all unnamed modules if <other-module> is\n\
+\ ALL-UNNAMED.\n\
\ --add-reads <module>=<other-module>(,<other-module>)*\n\
-\ Specify additional modules to be considered as required by a\n\
-\ given module. <other-module> may be ALL-UNNAMED to require\n\
-\ the unnamed module.\n\
-\ -Xmodule:<module-name> Specify a module to which the classes being compiled belong.\n\
+\ Specify additional modules to be considered as\n\
+\ required by a given module. <other-module> may be\n\
+\ ALL-UNNAMED to require the unnamed module.\n\
+\ -Xmodule:<module-name> Specify a module to which the classes being\n\
+\ compiled belong.\n\
\ --patch-module <module>=<file>(:<file>)*\n\
-\ Override or augment a module with classes and resources\n\
-\ in JAR files or directories\n\
+\ Override or augment a module with classes\n\
+\ and resources in JAR files or directories\n\
\ -Xold Invoke the legacy javadoc tool\n
main.Xusage.foot=\
@@ -95,13 +135,14 @@
main.requires_argument=option {0} requires an argument.
main.invalid_flag=invalid flag: {0}
-main.No_packages_or_classes_specified=No packages or classes specified.
-main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
+main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
+main.module_not_found=module {0} not found.\n
main.cant.read=cannot read {0}
main.Loading_source_files_for_package=Loading source files for package {0}...
main.Loading_source_file=Loading source file {0}...
main.Building_tree=Constructing Javadoc information...
main.no_source_files_for_package=No source files for package {0}
+main.package_not_found=Package {0} not found
main.fatal.error=fatal error
main.fatal.exception=fatal exception
main.out.of.memory=java.lang.OutOfMemoryError: Please increase memory.\n\
@@ -119,6 +160,7 @@
main.file_ignored=File ignored: "{0}" (not yet supported)
main.illegal_class_name=Illegal class name: "{0}"
main.illegal_package_name=Illegal package name: "{0}"
+main.illegal_option_value=Illegal option value: "{0}"
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
main.unsupported.release.version=release version {0} not supported
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
--- a/langtools/src/jdk.javadoc/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,10 @@
* questions.
*/
+/** Defines the implementation of the
+ * {@link javax.tools.ToolProvider#getSystemDocumentationTool system documentation tool}
+ * and its command line equivalent, <em>javadoc</em>.
+ */
module jdk.javadoc {
requires public java.compiler;
requires public jdk.compiler;
--- a/langtools/src/jdk.jdeps/share/classes/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jdeps/share/classes/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,6 +23,9 @@
* questions.
*/
+/** Defines tools for analysing dependencies in Java libraries and programs, including
+ * the <em>jdeps</em> and <em>javap</em> tools.
+ */
module jdk.jdeps {
requires java.base;
requires java.compiler;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Aug 29 08:53:32 2016 -0700
@@ -923,7 +923,7 @@
for (String alternative : alternatives) {
if (alternative.startsWith(input)) {
- result.add(new Suggestion(alternative, false));
+ result.add(new ArgSuggestion(alternative));
}
}
@@ -951,7 +951,7 @@
List<Suggestion> result = new ArrayList<>();
try (Stream<Path> dir = Files.list(current)) {
dir.filter(f -> accept.test(f) && f.getFileName().toString().startsWith(prefix))
- .map(f -> new Suggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : ""), false))
+ .map(f -> new ArgSuggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : "")))
.forEach(result::add);
} catch (IOException ex) {
//ignore...
@@ -959,7 +959,7 @@
if (path.isEmpty()) {
StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
.filter(root -> accept.test(root) && root.toString().startsWith(prefix))
- .map(root -> new Suggestion(root.toString(), false))
+ .map(root -> new ArgSuggestion(root.toString()))
.forEach(result::add);
}
anchor[0] = path.length();
@@ -981,7 +981,7 @@
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
: Stream.of(String.valueOf(k.id())))
.filter(k -> k.startsWith(prefix))
- .map(k -> new Suggestion(k, false))
+ .map(k -> new ArgSuggestion(k))
.collect(Collectors.toList());
};
}
@@ -1146,7 +1146,7 @@
.filter(cmd -> cmd.kind.shouldSuggestCompletions)
.map(cmd -> cmd.command)
.filter(key -> key.startsWith(prefix))
- .map(key -> new Suggestion(key + " ", false));
+ .map(key -> new ArgSuggestion(key + " "));
anchor[0] = 0;
} else {
String arg = prefix.substring(space + 1);
@@ -1919,7 +1919,7 @@
{
String val = state.status(vk) == Status.VALID
? state.varValue(vk)
- : "jshell.msg.vars.not.active";
+ : getResourceString("jshell.msg.vars.not.active");
hard(" %s %s = %s", vk.typeName(), vk.name(), val);
});
return true;
@@ -2457,6 +2457,42 @@
this.tid = tid;
}
}
+
+ private static class ArgSuggestion implements Suggestion {
+
+ private final String continuation;
+
+ /**
+ * Create a {@code Suggestion} instance.
+ *
+ * @param continuation a candidate continuation of the user's input
+ */
+ public ArgSuggestion(String continuation) {
+ this.continuation = continuation;
+ }
+
+ /**
+ * The candidate continuation of the given user's input.
+ *
+ * @return the continuation string
+ */
+ @Override
+ public String continuation() {
+ return continuation;
+ }
+
+ /**
+ * Indicates whether input continuation matches the target type and is thus
+ * more likely to be the desired continuation. A matching continuation is
+ * preferred.
+ *
+ * @return {@code false}, non-types analysis
+ */
+ @Override
+ public boolean matchesType() {
+ return false;
+ }
+ }
}
abstract class NonInteractiveIOContext extends IOContext {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Mon Aug 29 08:53:32 2016 -0700
@@ -503,10 +503,8 @@
/**
* Return all snippets.
* @return the snippets for all current snippets in id order.
- * @throws IllegalStateException if this JShell instance is closed.
*/
- public Stream<Snippet> snippets() throws IllegalStateException {
- checkIfAlive();
+ public Stream<Snippet> snippets() {
return maps.snippetList().stream();
}
@@ -517,9 +515,8 @@
* {@code && snippet.kind() == Kind.VARIABLE}
* and cast to {@code VarSnippet}.
* @return the active declared variables.
- * @throws IllegalStateException if this JShell instance is closed.
*/
- public Stream<VarSnippet> variables() throws IllegalStateException {
+ public Stream<VarSnippet> variables() {
return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.VAR)
.map(sn -> (VarSnippet) sn);
@@ -532,9 +529,8 @@
* {@code && snippet.kind() == Kind.METHOD}
* and cast to MethodSnippet.
* @return the active declared methods.
- * @throws IllegalStateException if this JShell instance is closed.
*/
- public Stream<MethodSnippet> methods() throws IllegalStateException {
+ public Stream<MethodSnippet> methods() {
return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.METHOD)
.map(sn -> (MethodSnippet)sn);
@@ -547,9 +543,8 @@
* {@code && snippet.kind() == Kind.TYPE_DECL}
* and cast to TypeDeclSnippet.
* @return the active declared type declarations.
- * @throws IllegalStateException if this JShell instance is closed.
*/
- public Stream<TypeDeclSnippet> types() throws IllegalStateException {
+ public Stream<TypeDeclSnippet> types() {
return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.TYPE_DECL)
.map(sn -> (TypeDeclSnippet) sn);
@@ -562,9 +557,8 @@
* {@code && snippet.kind() == Kind.IMPORT}
* and cast to ImportSnippet.
* @return the active declared import declarations.
- * @throws IllegalStateException if this JShell instance is closed.
*/
- public Stream<ImportSnippet> imports() throws IllegalStateException {
+ public Stream<ImportSnippet> imports() {
return snippets()
.filter(sn -> status(sn).isActive() && sn.kind() == Snippet.Kind.IMPORT)
.map(sn -> (ImportSnippet) sn);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Mon Aug 29 08:53:32 2016 -0700
@@ -144,30 +144,16 @@
/**
* The result of {@code analyzeCompletion(String input)}.
- * Describes the completeness and position of the first snippet in the given input.
+ * Describes the completeness of the first snippet in the given input.
*/
- public static class CompletionInfo {
-
- private final Completeness completeness;
- private final int unitEndPos;
- private final String source;
- private final String remaining;
-
- CompletionInfo(Completeness completeness, int unitEndPos, String source, String remaining) {
- this.completeness = completeness;
- this.unitEndPos = unitEndPos;
- this.source = source;
- this.remaining = remaining;
- }
+ public interface CompletionInfo {
/**
* The analyzed completeness of the input.
*
* @return an enum describing the completeness of the input string.
*/
- public Completeness completeness() {
- return completeness;
- }
+ Completeness completeness();
/**
* Input remaining after the complete part of the source.
@@ -175,9 +161,7 @@
* @return the portion of the input string that remains after the
* complete Snippet
*/
- public String remaining() {
- return remaining;
- }
+ String remaining();
/**
* Source code for the first Snippet of code input. For example, first
@@ -186,18 +170,7 @@
*
* @return the source of the first encountered Snippet
*/
- public String source() {
- return source;
- }
-
- /**
- * The end of the first Snippet of source.
- *
- * @return the position of the end of the first Snippet in the input.
- */
- public int unitEndPos() {
- return unitEndPos;
- }
+ String source();
}
/**
@@ -272,30 +245,14 @@
/**
* A candidate for continuation of the given user's input.
*/
- public static class Suggestion {
-
- private final String continuation;
- private final boolean matchesType;
-
- /**
- * Create a {@code Suggestion} instance.
- *
- * @param continuation a candidate continuation of the user's input
- * @param matchesType does the candidate match the target type
- */
- public Suggestion(String continuation, boolean matchesType) {
- this.continuation = continuation;
- this.matchesType = matchesType;
- }
+ public interface Suggestion {
/**
* The candidate continuation of the given user's input.
*
* @return the continuation string
*/
- public String continuation() {
- return continuation;
- }
+ String continuation();
/**
* Indicates whether input continuation matches the target type and is thus
@@ -305,9 +262,7 @@
* @return {@code true} if this suggested continuation matches the
* target type; otherwise {@code false}
*/
- public boolean matchesType() {
- return matchesType;
- }
+ boolean matchesType();
}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Mon Aug 29 08:53:32 2016 -0700
@@ -171,13 +171,13 @@
MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
if (mcm.endsWithOpenComment()) {
proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
- return new CompletionInfo(DEFINITELY_INCOMPLETE, srcInput.length(), null, srcInput + '\n');
+ return new CompletionInfoImpl(DEFINITELY_INCOMPLETE, null, srcInput + '\n');
}
String cleared = mcm.cleared();
String trimmedInput = Util.trimEnd(cleared);
if (trimmedInput.isEmpty()) {
// Just comment or empty
- return new CompletionInfo(Completeness.EMPTY, srcInput.length(), srcInput, "");
+ return new CompletionInfoImpl(Completeness.EMPTY, srcInput, "");
}
CaInfo info = ca.scan(trimmedInput);
Completeness status = info.status;
@@ -195,12 +195,12 @@
+ mcm.mask().substring(nonCommentNonWhiteLength);
proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
proc.debug(DBG_COMPA, " nothing remains.\n");
- return new CompletionInfo(status, unitEndPos, compileSource, "");
+ return new CompletionInfoImpl(status, compileSource, "");
} else {
String remain = srcInput.substring(unitEndPos);
proc.debug(DBG_COMPA, "Complete: %s\n", src);
proc.debug(DBG_COMPA, " remaining: %s\n", remain);
- return new CompletionInfo(status, unitEndPos, src, remain);
+ return new CompletionInfoImpl(status, src, remain);
}
case COMPLETE_WITH_SEMI:
// The unit is the whole non-coment/white input plus semicolon
@@ -209,19 +209,19 @@
+ mcm.mask().substring(nonCommentNonWhiteLength);
proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
proc.debug(DBG_COMPA, " nothing remains.\n");
- return new CompletionInfo(status, unitEndPos, compileSource, "");
+ return new CompletionInfoImpl(status, compileSource, "");
case DEFINITELY_INCOMPLETE:
proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+ return new CompletionInfoImpl(status, null, srcInput + '\n');
case CONSIDERED_INCOMPLETE:
proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+ return new CompletionInfoImpl(status, null, srcInput + '\n');
case EMPTY:
proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, srcInput, "");
+ return new CompletionInfoImpl(status, srcInput, "");
case UNKNOWN:
proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
- return new CompletionInfo(status, unitEndPos, srcInput, "");
+ return new CompletionInfoImpl(status, srcInput, "");
}
throw new InternalError();
}
@@ -665,7 +665,7 @@
if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
simpleName += paren.apply(hasParams.contains(simpleName));
}
- result.add(new Suggestion(simpleName, smart.test(c)));
+ result.add(new SuggestionImpl(simpleName, smart.test(c)));
}
}
@@ -1196,6 +1196,11 @@
fm.setLocationFromPaths(StandardLocation.SOURCE_PATH, sources);
} catch (IOException ex) {
proc.debug(ex, "SourceCodeAnalysisImpl.SourceCache.<init>(...)");
+ try {
+ fm.close();
+ } catch (IOException closeEx) {
+ proc.debug(closeEx, "SourceCodeAnalysisImpl.SourceCache.close()");
+ }
fm = null;
}
this.fm = fm;
@@ -1700,4 +1705,98 @@
}
}
}
+
+ /**
+ * A candidate for continuation of the given user's input.
+ */
+ private static class SuggestionImpl implements Suggestion {
+
+ private final String continuation;
+ private final boolean matchesType;
+
+ /**
+ * Create a {@code Suggestion} instance.
+ *
+ * @param continuation a candidate continuation of the user's input
+ * @param matchesType does the candidate match the target type
+ */
+ public SuggestionImpl(String continuation, boolean matchesType) {
+ this.continuation = continuation;
+ this.matchesType = matchesType;
+ }
+
+ /**
+ * The candidate continuation of the given user's input.
+ *
+ * @return the continuation string
+ */
+ @Override
+ public String continuation() {
+ return continuation;
+ }
+
+ /**
+ * Indicates whether input continuation matches the target type and is thus
+ * more likely to be the desired continuation. A matching continuation is
+ * preferred.
+ *
+ * @return {@code true} if this suggested continuation matches the
+ * target type; otherwise {@code false}
+ */
+ @Override
+ public boolean matchesType() {
+ return matchesType;
+ }
+ }
+
+ /**
+ * The result of {@code analyzeCompletion(String input)}.
+ * Describes the completeness and position of the first snippet in the given input.
+ */
+ private static class CompletionInfoImpl implements CompletionInfo {
+
+ private final Completeness completeness;
+ private final String source;
+ private final String remaining;
+
+ CompletionInfoImpl(Completeness completeness, String source, String remaining) {
+ this.completeness = completeness;
+ this.source = source;
+ this.remaining = remaining;
+ }
+
+ /**
+ * The analyzed completeness of the input.
+ *
+ * @return an enum describing the completeness of the input string.
+ */
+ @Override
+ public Completeness completeness() {
+ return completeness;
+ }
+
+ /**
+ * Input remaining after the complete part of the source.
+ *
+ * @return the portion of the input string that remains after the
+ * complete Snippet
+ */
+ @Override
+ public String remaining() {
+ return remaining;
+ }
+
+ /**
+ * Source code for the first Snippet of code input. For example, first
+ * statement, or first method declaration. Trailing semicolons will be
+ * added, as needed.
+ *
+ * @return the source of the first encountered Snippet
+ */
+ @Override
+ public String source() {
+ return source;
+ }
+ }
+
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DefaultLoaderDelegate.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DefaultLoaderDelegate.java Mon Aug 29 08:53:32 2016 -0700
@@ -77,6 +77,7 @@
public DefaultLoaderDelegate() {
this.loader = new RemoteClassLoader();
+ Thread.currentThread().setContextClassLoader(loader);
}
@Override
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/ExecutionControlForwarder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/ExecutionControlForwarder.java Mon Aug 29 08:53:32 2016 -0700
@@ -44,6 +44,13 @@
*/
class ExecutionControlForwarder {
+ /**
+ * Maximum number of characters for writeUTF(). Byte maximum is 65535, at
+ * maximum three bytes per character that is 65535 / 3 == 21845. Minus one
+ * for safety.
+ */
+ private static final int MAX_UTF_CHARS = 21844;
+
private final ExecutionControl ec;
private final ObjectInput in;
private final ObjectOutput out;
@@ -89,6 +96,9 @@
private void writeUTF(String s) throws IOException {
if (s == null) {
s = "";
+ } else if (s.length() > MAX_UTF_CHARS) {
+ // Truncate extremely long strings to prevent writeUTF from crashing the VM
+ s = s.substring(0, MAX_UTF_CHARS);
}
out.writeUTF(s);
}
--- a/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
import java.nio.file.Files;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
@@ -157,7 +158,7 @@
private final Map<File,SoftReference<String>> fileContentCache = new HashMap<>();
/** Stream used for logging messages. */
- private final PrintStream out = System.out;
+ protected final PrintStream out = System.out;
/** The directory containing the source code for the test. */
public static final String testSrc = System.getProperty("test.src");
@@ -416,6 +417,17 @@
* @param paths the files to check, within the most recent output directory.
* */
public void checkFiles(boolean expectedFound, String... paths) {
+ checkFiles(expectedFound, Arrays.asList(paths));
+ }
+
+ /**
+ * Check for files in (or not in) the generated output.
+ * @param expectedFound true if all of the files are expected
+ * to be found, or false if all of the files are expected to be
+ * not found
+ * @param paths the files to check, within the most recent output directory.
+ * */
+ public void checkFiles(boolean expectedFound, Collection<String> paths) {
for (String path: paths) {
// log.logCheckFile(path, expectedFound);
checking("checkFile");
@@ -574,7 +586,7 @@
return content;
content = new String(Files.readAllBytes(file.toPath()));
- fileContentCache.put(file, new SoftReference(content));
+ fileContentCache.put(file, new SoftReference<>(content));
return content;
} catch (FileNotFoundException e) {
System.err.println(e);
@@ -613,16 +625,19 @@
* Print a summary of the test results.
*/
protected void printSummary() {
-// log.write();
+ String javadocRuns = (javadocRunNum <= 1) ? ""
+ : ", in " + javadocRunNum + " runs of javadoc";
+
if (numTestsRun != 0 && numTestsPassed == numTestsRun) {
// Test passed
out.println();
- out.println("All " + numTestsPassed + " subtests passed");
+ out.println("All " + numTestsPassed + " subtests passed" + javadocRuns);
} else {
// Test failed
throw new Error((numTestsRun - numTestsPassed)
+ " of " + (numTestsRun)
- + " subtests failed");
+ + " subtests failed"
+ + javadocRuns);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8163800
+ * @summary The fix for JDK-8072052 shows up other minor incorrect use of styles
+ * @library ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build JavadocTester
+ * @build TestClassLinks
+ * @run main TestClassLinks
+ */
+
+public class TestClassLinks extends JavadocTester {
+
+ public static void main(String... args) throws Exception {
+ TestClassLinks tester = new TestClassLinks();
+ tester.runTests();
+ }
+
+ @Test
+ void test() {
+
+ javadoc("-d", "out",
+ "-Xdoclint:none",
+ "-sourcepath", testSrc,
+ "-package",
+ "p");
+ checkExit(Exit.OK);
+
+ checkOutput("p/C1.html", true,
+ "<code><a href=\"../p/C2.html\" title=\"class in p\">C2</a></code>",
+ "<code><span class=\"memberNameLink\"><a href=\"../p/C1.html#C1--\">C1</a></span>()</code>");
+
+ checkOutput("p/C2.html", true,
+ "<code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>",
+ "<code><span class=\"memberNameLink\"><a href=\"../p/C2.html#C2--\">C2</a></span>()</code>");
+
+ checkOutput("p/C3.html", true,
+ "<code><a href=\"../p/I1.html\" title=\"interface in p\">I1</a></code>, "
+ + "<code><a href=\"../p/I12.html\" title=\"interface in p\">I12</a></code>, "
+ + "<code><a href=\"../p/I2.html\" title=\"interface in p\">I2</a></code>, "
+ + "<code><a href=\"../p/IT1.html\" title=\"interface in p\">IT1</a><T></code>, "
+ + "<code><a href=\"../p/IT2.html\" title=\"interface in p\">IT2</a><java.lang.String></code>",
+ "<code><span class=\"memberNameLink\"><a href=\"../p/C3.html#C3--\">C3</a></span>()</code>");
+
+ checkOutput("p/I1.html", true,
+ "<code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>",
+ "<code><a href=\"../p/I12.html\" title=\"interface in p\">I12</a></code>");
+
+ checkOutput("p/I2.html", true,
+ "<code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>",
+ "<code><a href=\"../p/I12.html\" title=\"interface in p\">I12</a></code>");
+
+ checkOutput("p/I12.html", true,
+ "<code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>",
+ "<code><a href=\"../p/I1.html\" title=\"interface in p\">I1</a></code>, <code><a href=\"../p/I2.html\" title=\"interface in p\">I2</a></code>");
+
+ checkOutput("p/IT1.html", true,
+ "<code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>");
+
+ checkOutput("p/IT2.html", true,
+ "code><a href=\"../p/C3.html\" title=\"class in p\">C3</a></code>");
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testClassLinks/p/C.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package p;
+
+interface I1 { }
+
+interface I2 { }
+
+interface I12 extends I1, I2 { }
+
+interface IT1<T> { }
+
+interface IT2<T> { }
+
+class C1 { }
+
+class C2 extends C1 { }
+
+class C3<T> extends C2 implements I12, IT1<T>, IT2<String> { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8162353
+ * @summary javadoc should provide a way to disable use of frames
+ * @library /tools/lib ../lib
+ * @modules
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * jdk.javadoc/jdk.javadoc.internal.tool
+ * @build toolbox.ModuleBuilder toolbox.ToolBox
+ * @build JavadocTester
+ * @run main TestFramesNoFrames
+ */
+
+import java.io.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.*;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import toolbox.ModuleBuilder;
+import toolbox.ToolBox;
+
+public class TestFramesNoFrames extends JavadocTester {
+
+ public static void main(String... args) throws Exception {
+ TestFramesNoFrames tester = new TestFramesNoFrames();
+ tester.generateSource();
+ tester.runTests();
+ }
+
+ ToolBox tb = new ToolBox();
+ Path gensrcModules = Paths.get("gensrc/modules");
+ Path gensrcPackages = Paths.get("gensrc/packages");
+
+ void generateSource() throws IOException {
+ String[] modules = { "", "m1", "m2", "m3" };
+ String[] packages = { "p1", "p2", "p3" };
+ String[] classes = { "C1", "C2", "C3" };
+ for (String m: modules) {
+ ModuleBuilder mb = m.equals("") ? null : new ModuleBuilder(tb, m);
+ for (String p: packages) {
+ Path pkgRoot;
+ if (m.equals("")) {
+ pkgRoot = gensrcPackages;
+ } else {
+ pkgRoot = gensrcModules.resolve(m);
+ mb.exports(m + p);
+ }
+ for (String c: classes) {
+ tb.writeJavaFiles(pkgRoot,
+ "package " + (m + p) + ";\n"
+ + "/** class " + (m + p + c).toUpperCase() + ". */\n"
+ + "public class " + (m + p + c).toUpperCase() + " { }"
+ );
+ }
+ }
+ if (!m.equals("")) {
+ mb.write(gensrcModules);
+ }
+ }
+ tb.writeFile("overview.html",
+ "<html><body>This is the overview file</body></html>");
+ }
+
+ enum FrameKind {
+ DEFAULT(),
+ FRAMES("--frames"),
+ NO_FRAMES("--no-frames");
+ FrameKind(String... opts) {
+ this.opts = Arrays.asList(opts);
+ }
+ final List<String> opts;
+ }
+
+ enum OverviewKind {
+ DEFAULT(),
+ OVERVIEW("-overview", "overview.html"),
+ NO_OVERVIEW("-nooverview");
+ OverviewKind(String... opts) {
+ this.opts = Arrays.asList(opts);
+ }
+ final List<String> opts;
+ }
+
+ enum HtmlKind {
+ HTML4("-html4"),
+ HTML5("-html5");
+ HtmlKind(String... opts) {
+ this.opts = Arrays.asList(opts);
+ }
+ final List<String> opts;
+ }
+
+ @Override
+ public void runTests() throws Exception {
+ for (Method m : getClass().getDeclaredMethods()) {
+ Annotation a = m.getAnnotation(Test.class);
+ if (a != null) {
+ for (FrameKind fk : FrameKind.values()) {
+ for (OverviewKind ok : OverviewKind.values()) {
+ for (HtmlKind hk : HtmlKind.values()) {
+ try {
+ out.println("Running test " + m.getName() + " " + fk + " " + ok + " " + hk);
+ Path base = Paths.get(m.getName() + "_" + fk + "_" + ok + "_" + hk);
+ Files.createDirectories(base);
+ m.invoke(this, new Object[]{base, fk, ok, hk});
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ throw (cause instanceof Exception) ? ((Exception) cause) : e;
+ }
+ out.println();
+ }
+ }
+ }
+ }
+ }
+ printSummary();
+ }
+
+ void javadoc(Path outDir, FrameKind fKind, OverviewKind oKind, HtmlKind hKind, String... rest) {
+ List<String> args = new ArrayList<>();
+ args.add("-d");
+ args.add(outDir.toString());
+ args.addAll(fKind.opts);
+ args.addAll(oKind.opts);
+ args.addAll(hKind.opts);
+ args.addAll(Arrays.asList(rest));
+ javadoc(args.toArray(new String[0]));
+ checkExit(Exit.OK);
+ }
+
+ @Test
+ void testClass(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws Exception {
+ javadoc(base, fKind, oKind, hKind,
+ gensrcPackages.resolve("p1/P1C1.java").toString());
+
+ new Checker(fKind, oKind, hKind)
+ .classes("p1.P1C1")
+ .check();
+ }
+
+ @Test
+ void testClasses(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
+ javadoc(base, fKind, oKind, hKind,
+ gensrcPackages.resolve("p1/P1C1.java").toString(),
+ gensrcPackages.resolve("p1/P1C2.java").toString(),
+ gensrcPackages.resolve("p1/P1C3.java").toString());
+
+ new Checker(fKind, oKind, hKind)
+ .classes("p1.P1C1", "p1.P1C2", "p1.P1C3")
+ .check();
+ }
+
+ @Test
+ void testPackage(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
+ javadoc(base, fKind, oKind, hKind,
+ "-sourcepath", gensrcPackages.toString(),
+ "p1");
+
+ new Checker(fKind, oKind, hKind)
+ .classes("p1.P1C1", "p1.P1C2", "p1.P1C3")
+ .check();
+ }
+
+ @Test
+ void testPackages(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
+ javadoc(base, fKind, oKind, hKind,
+ "-sourcepath", gensrcPackages.toString(),
+ "p1", "p2", "p3");
+
+ new Checker(fKind, oKind, hKind)
+ .classes("p1.P1C1", "p1.P1C2", "p1.P1C3",
+ "p2.P2C1", "p2.P2C2", "p2.P2C3",
+ "p3.P3C1", "p3.P3C2", "p3.P3C3")
+ .check();
+ }
+
+ @Test
+ void testModules(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
+ javadoc(base, fKind, oKind, hKind,
+ "-modulesourcepath", gensrcModules.toString(),
+ "--module", "m1,m2,m3");
+
+ new Checker(fKind, oKind, hKind)
+ .classes("m1/m1p1.M1P1C1", "m1/m1p1.M1P1C2", "m1/m1p1.M1P1C3",
+ "m2/m2p1.M2P1C1", "m2/m2p1.M2P1C2", "m2/m2p1.M2P1C3",
+ "m3/m3p1.M3P1C1", "m3/m3p1.M3P1C2", "m3/m3p1.M3P1C3")
+ .check();
+ }
+
+ /**
+ * Check the contents of the generated output, according to the
+ * specified options.
+ */
+ class Checker {
+ private final FrameKind fKind;
+ private final OverviewKind oKind;
+ private final HtmlKind hKind;
+ List<String> classes;
+
+ private boolean frames;
+ private boolean overview;
+
+ Checker(FrameKind fKind, OverviewKind oKind, HtmlKind hKind) {
+ this.fKind = fKind;
+ this.oKind = oKind;
+ this.hKind = hKind;
+ }
+
+ Checker classes(String... classes) {
+ this.classes = Arrays.asList(classes);
+ return this;
+ }
+
+ void check() throws IOException {
+ switch (fKind) {
+ case DEFAULT:
+ case FRAMES:
+ frames = true;
+ break;
+
+ case NO_FRAMES:
+ frames = false;
+ break;
+ }
+
+ switch (oKind) {
+ case DEFAULT:
+ overview = (getPackageCount() > 1);
+ break;
+
+ case OVERVIEW:
+ overview = true;
+ break;
+
+ case NO_OVERVIEW:
+ overview = false;
+ break;
+ }
+
+ checkAllClassesFiles();
+ checkFrameFiles();
+ checkOverviewSummary();
+
+ checkIndex();
+ checkNavBar();
+ checkHelpDoc();
+
+ }
+
+ private void checkAllClassesFiles() {
+ // these files are only generated in frames mode
+ checkFiles(frames,
+ "allclasses-frame.html",
+ "allclasses-noframe.html");
+
+ // this file is only generated when not in frames mode
+ checkFiles(!frames,
+ "allclasses.html");
+ }
+
+ private void checkFrameFiles() {
+ // these files are all only generated in frames mode
+
+ // <module>-frame.html and <module>-type-frame.html files
+ checkFiles(frames, classes.stream()
+ .filter(c -> isInModule(c))
+ .map(c -> modulePart(c))
+ .flatMap(m -> Arrays.asList(
+ m + "-frame.html",
+ m + "-type-frame.html").stream())
+ .collect(Collectors.toSet()));
+
+ // <package>/package-frame.html files
+ checkFiles(frames, classes.stream()
+ .map(c -> packagePart(c) + "/package-frame.html")
+ .collect(Collectors.toSet()));
+ }
+
+ private void checkHelpDoc() {
+ // the Help page only describes Frame/NoFrames in frames mode
+ checkOutput("help-doc.html", frames,
+ "<h2>Frames/No Frames</h2>");
+ }
+
+ private void checkIndex() {
+ // the index.html page only contains frames in frames mode
+ checkOutput("index.html", frames,
+ "<iframe ",
+ "</iframe>");
+
+ // the index.html contains the overview if one
+ // has been given, and not in frames mode
+ checkOutput("index.html", !frames && oKind == OverviewKind.OVERVIEW,
+ "This is the overview file");
+
+ // the index.html file contains a summary table
+ // if an overview was generated and not in frames mode
+ checkOutput("index.html", !frames && overview,
+ "<table class=\"overviewSummary\"");
+
+ // the index.html file contains a redirect if
+ // no frames and no overview
+ checkOutput("index.html", !frames && !overview,
+ "<meta http-equiv=\"Refresh\" content=\"0;",
+ "<script type=\"text/javascript\">window.location.replace(");
+
+ // the index.html file <meta> refresh should only use <noscript> in HTML 5
+ if (!frames && !overview) {
+ checkOutput("index.html", hKind == HtmlKind.HTML5,
+ "<noscript>\n<meta http-equiv=\"Refresh\" content=\"0;");
+ }
+ }
+
+ private void checkNavBar() {
+ // the files containing a navigation bar should only
+ // contain FRAMES/NO-FRAMES links in frames mode
+ List<String> navbarFiles = new ArrayList<>();
+ navbarFiles.addAll(classes.stream()
+ .map(c -> toHtml(packageClassPart(c)))
+ .collect(Collectors.toSet()));
+ for (String f : navbarFiles) {
+ checkOutput(f, frames,
+ "target=\"_top\">Frames</a>",
+ "target=\"_top\">No Frames</a>");
+ }
+ }
+
+ private void checkOverviewSummary() {
+ // the overview-summary.html file only appears if
+ // in frames mode and (overview requested or multiple packages)
+ checkFiles(frames && overview,
+ "overview-summary.html");
+ }
+
+ private long getPackageCount() {
+ return this.classes.stream()
+ .filter(name -> name.contains("."))
+ .map(name -> name.substring(0, name.lastIndexOf(".")))
+ .distinct()
+ .count();
+ }
+
+ private String packagePart(String className) {
+ int slash = className.indexOf("/");
+ int lastDot = className.lastIndexOf(".");
+ return className.substring(slash + 1, lastDot);
+ }
+
+ private String packageClassPart(String className) {
+ int slash = className.indexOf("/");
+ return className.substring(slash + 1);
+ }
+
+ private boolean isInModule(String className) {
+ return className.contains("/");
+ }
+
+ private String modulePart(String className) {
+ int slash = className.indexOf("/");
+ return className.substring(0, slash);
+ }
+
+ private String toHtml(String className) {
+ return className.replace(".", "/") + ".html";
+ }
+ }
+}
--- a/langtools/test/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java Mon Aug 29 08:53:32 2016 -0700
@@ -54,9 +54,9 @@
"<a name=\"visibleField\">",
"<a name=\"visibleMethod--\">",
"<dt>Direct Known Subclasses:</dt>\n" +
- "<dd><a href=\"../pkg1/A.VisibleInner.html\" title=\"class in pkg1\">" +
- "A.VisibleInner</a>, <a href=\"../pkg1/A.VisibleInnerExtendsInvisibleInner.html\" " +
- "title=\"class in pkg1\">A.VisibleInnerExtendsInvisibleInner</a></dd>");
+ "<dd><code><a href=\"../pkg1/A.VisibleInner.html\" title=\"class in pkg1\">" +
+ "A.VisibleInner</a></code>, <code><a href=\"../pkg1/A.VisibleInnerExtendsInvisibleInner.html\" " +
+ "title=\"class in pkg1\">A.VisibleInnerExtendsInvisibleInner</a></code></dd>");
checkOutput("pkg1/A.html", false,
"<a name=\"inVisibleField\">",
--- a/langtools/test/jdk/javadoc/doclet/testInterface/TestInterface.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testInterface/TestInterface.java Mon Aug 29 08:53:32 2016 -0700
@@ -36,7 +36,7 @@
*/
/*
- * TODO: make it Inteferface<PE> ie. fix all ParameterTypes, likely should get
+ * TODO: make it Interface<PE> ie. fix all ParameterTypes, likely should get
* fixed when Doc is replace by j.l.m, but meanwhile this test has been adjusted
* take the current format this is better than @ignore because we can follow the
* differences as the work progress.
@@ -69,17 +69,17 @@
// Make sure known implementing class list is correct and omits type parameters.
"<dl>\n"
+ "<dt>All Known Implementing Classes:</dt>\n"
- + "<dd><a href=\"../pkg/Child.html\" title=\"class in pkg\">Child"
- + "</a>, <a href=\"../pkg/Parent.html\" title=\"class in pkg\">Parent"
- + "</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/Child.html\" title=\"class in pkg\">Child"
+ + "</a></code>, <code><a href=\"../pkg/Parent.html\" title=\"class in pkg\">Parent"
+ + "</a></code></dd>\n"
+ "</dl>");
checkOutput("pkg/Child.html", true,
// Make sure "All Implemented Interfaces": has substituted type parameters
"<dl>\n"
+ "<dt>All Implemented Interfaces:</dt>\n"
- + "<dd><a href=\"../pkg/Interface.html\" title=\"interface in pkg\">"
- + "Interface</a><CE></dd>\n"
+ + "<dd><code><a href=\"../pkg/Interface.html\" title=\"interface in pkg\">"
+ + "Interface</a><CE></code></dd>\n"
+ "</dl>",
//Make sure Class Tree has substituted type parameters.
"<ul class=\"inheritance\">\n"
@@ -114,8 +114,8 @@
//Make sure "Direct Know Subclasses" omits type parameters
"<dl>\n"
+ "<dt>Direct Known Subclasses:</dt>\n"
- + "<dd><a href=\"../pkg/Child.html\" title=\"class in pkg\">Child"
- + "</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/Child.html\" title=\"class in pkg\">Child"
+ + "</a></code></dd>\n"
+ "</dl>");
checkOutput("pkg/Interface.html", false,
--- a/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java Mon Aug 29 08:53:32 2016 -0700
@@ -70,5 +70,7 @@
checkOutput(Output.OUT, false,
"Tag @see: reference not found: A");
+
+ checkFiles(false, "checkPkg/A.html");
}
}
--- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8154119 8154262 8156077 8157987 8154261 8154817
+ * @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995
* @summary Test modules support in javadoc.
* @author bpatel
* @library ../lib
@@ -31,7 +31,6 @@
* @build JavadocTester
* @run main TestModules
*/
-
public class TestModules extends JavadocTester {
public static void main(String... args) throws Exception {
@@ -39,72 +38,112 @@
tester.runTests();
}
+ /**
+ * Test generated module pages for HTML 4.
+ */
@Test
- void test1() {
+ void testHtml4() {
javadoc("-d", "out", "-use",
"--module-source-path", testSrc,
"--add-modules", "module1,module2",
"testpkgmdl1", "testpkgmdl2");
checkExit(Exit.OK);
- testDescription(true);
- testNoDescription(false);
- testOverviewSummaryModules();
- testModuleLink();
- testModuleClickThroughLinks();
- testModuleClickThrough(true);
+ checkDescription(true);
+ checkNoDescription(false);
+ checkOverviewSummaryModules();
+ checkModuleLink();
+ checkModuleClickThroughLinks();
+ checkModuleClickThrough(true);
+ checkModuleFilesAndLinks(true);
+ checkModulesInSearch(true);
}
+ /**
+ * Test generated module pages for HTML 5.
+ */
@Test
- void test2() {
+ void testHtml5() {
javadoc("-d", "out-html5", "-html5", "-use",
"--module-source-path", testSrc,
"--add-modules", "module1,module2",
"testpkgmdl1", "testpkgmdl2");
checkExit(Exit.OK);
- testHtml5Description(true);
- testHtml5NoDescription(false);
- testHtml5OverviewSummaryModules();
- testModuleLink();
- testModuleClickThroughLinks();
- testModuleClickThrough(true);
+ checkHtml5Description(true);
+ checkHtml5NoDescription(false);
+ checkHtml5OverviewSummaryModules();
+ checkModuleLink();
+ checkModuleClickThroughLinks();
+ checkModuleClickThrough(true);
+ checkModuleFilesAndLinks(true);
+ checkModulesInSearch(true);
}
+ /**
+ * Test generated module pages for HTML 4 with -nocomment option.
+ */
@Test
- void test3() {
+ void testHtml4NoComment() {
javadoc("-d", "out-nocomment", "-nocomment", "-use",
"--module-source-path", testSrc,
"--add-modules", "module1,module2",
"testpkgmdl1", "testpkgmdl2");
checkExit(Exit.OK);
- testDescription(false);
- testNoDescription(true);
- testModuleLink();
+ checkDescription(false);
+ checkNoDescription(true);
+ checkModuleLink();
+ checkModuleFilesAndLinks(true);
}
+ /**
+ * Test generated module pages for HTML 5 with -nocomment option.
+ */
@Test
- void test4() {
+ void testHtml5NoComment() {
javadoc("-d", "out-html5-nocomment", "-nocomment", "-html5", "-use",
"--module-source-path", testSrc,
"--add-modules", "module1,module2",
"testpkgmdl1", "testpkgmdl2");
checkExit(Exit.OK);
- testHtml5Description(false);
- testHtml5NoDescription(true);
- testModuleLink();
+ checkHtml5Description(false);
+ checkHtml5NoDescription(true);
+ checkModuleLink();
+ checkModuleFilesAndLinks(true);
}
- @Test
- void test5() {
+ /**
+ * Test generated pages, in an unnamed module, for HTML 4.
+ */
+ @Test
+ void testHtml4UnnamedModule() {
javadoc("-d", "out-nomodule", "-use",
"-sourcepath", testSrc,
"testpkgnomodule", "testpkgnomodule1");
checkExit(Exit.OK);
- testOverviewSummaryPackages();
- testModuleClickThrough(false);
+ checkOverviewSummaryPackages();
+ checkModuleClickThrough(false);
+ checkModuleFilesAndLinks(false);
+ checkModulesInSearch(false);
}
- @Test
- void test6() {
+ /**
+ * Test generated pages, in an unnamed module, for HTML 5.
+ */
+ @Test
+ void testHtml5UnnamedModule() {
+ javadoc("-d", "out-html5-nomodule", "-html5", "-use",
+ "-sourcepath", testSrc,
+ "testpkgnomodule", "testpkgnomodule1");
+ checkExit(Exit.OK);
+ checkHtml5OverviewSummaryPackages();
+ checkModuleFilesAndLinks(false);
+ checkModulesInSearch(false);
+ }
+
+ /**
+ * Test generated module pages with javadoc tags.
+ */
+ @Test
+ void testJDTagsInModules() {
javadoc("-d", "out-mdltags", "-author", "-version",
"-tag", "regular:a:Regular Tag:",
"-tag", "moduletag:s:Module Tag:",
@@ -112,45 +151,54 @@
"--add-modules", "moduletags,module2",
"testpkgmdltags", "testpkgmdl2");
checkExit(Exit.OK);
- testModuleTags();
+ checkModuleTags();
}
+ /**
+ * Test generated module summary page.
+ */
@Test
- void test7() {
+ void testModuleSummary() {
javadoc("-d", "out-moduleSummary", "-use",
"-modulesourcepath", testSrc,
"-addmods", "module1,module2",
- "testpkgmdl1", "testpkgmdl2", "testpkg2mdl2");
+ "testpkgmdl1", "testpkgmdl2", "module2/testpkg2mdl2");
checkExit(Exit.OK);
- testModuleSummary();
- testNegatedModuleSummary();
+ checkModuleSummary();
+ checkNegatedModuleSummary();
}
- @Test
- void test8() {
- javadoc("-d", "out-html5-nomodule", "-html5", "-use",
- "-sourcepath", testSrc,
- "testpkgnomodule", "testpkgnomodule1");
+ /**
+ * Test generated module pages and pages with link to modules.
+ */
+ @Test
+ void testModuleFilesAndLinks() {
+ javadoc("-d", "out-modulelinks",
+ "-modulesourcepath", testSrc,
+ "-addmods", "module1",
+ "testpkgmdl1");
checkExit(Exit.OK);
- testHtml5OverviewSummaryPackages();
+ checkModuleFilesAndLinks(true);
}
- void testDescription(boolean found) {
+ void checkDescription(boolean found) {
checkOutput("module1-summary.html", found,
"<!-- ============ MODULE DESCRIPTION =========== -->\n"
+ "<a name=\"module.description\">\n"
+ "<!-- -->\n"
+ "</a>\n"
- + "<div class=\"block\">This is a test description for the module1 module.</div>");
+ + "<div class=\"block\">This is a test description for the module1 module. Search "
+ + "phrase <a id=\"searchphrase\">search phrase</a>.</div>");
checkOutput("module2-summary.html", found,
"<!-- ============ MODULE DESCRIPTION =========== -->\n"
+ "<a name=\"module.description\">\n"
+ "<!-- -->\n"
+ "</a>\n"
- + "<div class=\"block\">This is a test description for the module2 module.</div>");
+ + "<div class=\"block\">This is a test description for the module2 module. Search "
+ + "word <a id=\"search_word\">search_word</a> with no description.</div>");
}
- void testNoDescription(boolean found) {
+ void checkNoDescription(boolean found) {
checkOutput("module1-summary.html", found,
"<div class=\"contentContainer\">\n"
+ "<ul class=\"blockList\">\n"
@@ -167,26 +215,26 @@
+ "<!-- ============ MODULES SUMMARY =========== -->");
}
- void testHtml5Description(boolean found) {
+ void checkHtml5Description(boolean found) {
checkOutput("module1-summary.html", found,
"<section role=\"region\">\n"
+ "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+ "<a id=\"module.description\">\n"
+ "<!-- -->\n"
+ "</a>\n"
- + "<div class=\"block\">This is a test description for the module1 module.</div>\n"
- + "</section>");
+ + "<div class=\"block\">This is a test description for the module1 module. Search "
+ + "phrase <a id=\"searchphrase\">search phrase</a>.</div>");
checkOutput("module2-summary.html", found,
"<section role=\"region\">\n"
+ "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+ "<a id=\"module.description\">\n"
+ "<!-- -->\n"
+ "</a>\n"
- + "<div class=\"block\">This is a test description for the module2 module.</div>\n"
- + "</section>");
+ + "<div class=\"block\">This is a test description for the module2 module. Search "
+ + "word <a id=\"search_word\">search_word</a> with no description.</div>");
}
- void testHtml5NoDescription(boolean found) {
+ void checkHtml5NoDescription(boolean found) {
checkOutput("module1-summary.html", found,
"<div class=\"contentContainer\">\n"
+ "<ul class=\"blockList\">\n"
@@ -203,17 +251,13 @@
+ "<!-- ============ MODULES SUMMARY =========== -->");
}
- void testModuleLink() {
+ void checkModuleLink() {
checkOutput("overview-summary.html", true,
"<li>Module</li>");
checkOutput("module1-summary.html", true,
"<li class=\"navBarCell1Rev\">Module</li>");
checkOutput("module2-summary.html", true,
"<li class=\"navBarCell1Rev\">Module</li>");
- checkOutput("testpkgmdl1/package-summary.html", true,
- "<li><a href=\"../module1-summary.html\">Module</a></li>");
- checkOutput("testpkgmdl1/TestClassInModule1.html", true,
- "<li><a href=\"../module1-summary.html\">Module</a></li>");
checkOutput("testpkgmdl1/class-use/TestClassInModule1.html", true,
"<li><a href=\"../../module1-summary.html\">Module</a></li>");
checkOutput("testpkgmdl2/package-summary.html", true,
@@ -224,7 +268,7 @@
"<li><a href=\"../../module2-summary.html\">Module</a></li>");
}
- void testNoModuleLink() {
+ void checkNoModuleLink() {
checkOutput("testpkgnomodule/package-summary.html", true,
"<ul class=\"navList\" title=\"Navigation\">\n"
+ "<li><a href=\"../testpkgnomodule/package-summary.html\">Package</a></li>");
@@ -236,7 +280,7 @@
+ "<li><a href=\"../../testpkgnomodule/package-summary.html\">Package</a></li>");
}
- void testModuleTags() {
+ void checkModuleTags() {
checkOutput("moduletags-summary.html", true,
"Type Link: <a href=\"testpkgmdltags/TestClassInModuleTags.html\" title=\"class in "
+ "testpkgmdltags\"><code>TestClassInModuleTags</code></a>.");
@@ -270,7 +314,7 @@
+ "<dd>Just a simple module tag.</dd>");
}
- void testOverviewSummaryModules() {
+ void checkOverviewSummaryModules() {
checkOutput("overview-summary.html", true,
"<table class=\"overviewSummary\" summary=\"Module Summary table, listing modules, and an explanation\">\n"
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>\n"
@@ -287,7 +331,7 @@
+ "</tr>");
}
- void testOverviewSummaryPackages() {
+ void checkOverviewSummaryPackages() {
checkOutput("overview-summary.html", false,
"<table class=\"overviewSummary\" summary=\"Module Summary table, listing modules, and an explanation\">\n"
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>\n"
@@ -304,7 +348,7 @@
+ "</tr>");
}
- void testHtml5OverviewSummaryModules() {
+ void checkHtml5OverviewSummaryModules() {
checkOutput("overview-summary.html", true,
"<table class=\"overviewSummary\">\n"
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>\n"
@@ -321,7 +365,7 @@
+ "</tr>");
}
- void testHtml5OverviewSummaryPackages() {
+ void checkHtml5OverviewSummaryPackages() {
checkOutput("overview-summary.html", false,
"<table class=\"overviewSummary\">\n"
+ "<caption><span>Modules</span><span class=\"tabEnd\"> </span></caption>\n"
@@ -338,7 +382,7 @@
+ "</tr>");
}
- void testModuleSummary() {
+ void checkModuleSummary() {
checkOutput("module1-summary.html", true,
"<ul class=\"subNavList\">\n"
+ "<li>Module: </li>\n"
@@ -380,7 +424,8 @@
+ "</a>");
checkOutput("module2-summary.html", true,
"<tr class=\"rowColor\">\n"
- + "<td class=\"colFirst\">testpkg2mdl2</td>\n"
+ + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/package-summary.html\">"
+ + "testpkg2mdl2</a></td>\n"
+ "<td class=\"colSecond\">module1</td>\n"
+ "<td class=\"colLast\"> </td>\n"
+ "</tr>");
@@ -407,9 +452,10 @@
+ "</tr>");
checkOutput("module2-summary.html", true,
"<tr class=\"altColor\">\n"
- + "<td class=\"colFirst\">testpkg2mdl2.TestInterfaceInModule2<br>(<span "
- + "class=\"implementationLabel\">Implementation:</span> <a "
- + "href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
+ + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/TestInterfaceInModule2.html\" "
+ + "title=\"interface in testpkg2mdl2\">TestInterfaceInModule2</a><br>"
+ + "(<span class=\"implementationLabel\">Implementation:</span> "
+ + "<a href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
+ "TestClassInModule2</a>)</td>\n"
+ "<td class=\"colLast\"> </td>\n"
+ "</tr");
@@ -440,7 +486,7 @@
+ "</tr>");
}
- void testNegatedModuleSummary() {
+ void checkNegatedModuleSummary() {
checkOutput("module1-summary.html", false,
"<!-- ============ SERVICES SUMMARY =========== -->\n"
+ "<a name=\"services.summary\">\n"
@@ -448,7 +494,7 @@
+ "</a>");
}
- void testModuleClickThroughLinks() {
+ void checkModuleClickThroughLinks() {
checkOutput("module-overview-frame.html", true,
"<li><a href=\"module1-frame.html\" target=\"packageListFrame\" "
+ "onclick=\"updateModuleFrame('module1-type-frame.html','module1-summary.html');"
@@ -458,16 +504,56 @@
+ "onclick=\"updateModuleFrame('module2-type-frame.html','module2-summary.html');"
+ "\">module2</a></li>");
checkOutput("script.js", true,
- "function updateModuleFrame(pFrame, cFrame)\n"
- + "{\n"
- + " top.packageFrame.location = pFrame;\n"
- + " top.classFrame.location = cFrame;\n"
- + "}");
-}
+ "function updateModuleFrame(pFrame, cFrame)\n"
+ + "{\n"
+ + " top.packageFrame.location = pFrame;\n"
+ + " top.classFrame.location = cFrame;\n"
+ + "}");
+ }
- void testModuleClickThrough(boolean found) {
+ void checkModuleClickThrough(boolean found) {
checkFiles(found,
"module1-type-frame.html",
"module2-type-frame.html");
- }
+ }
+
+ void checkModuleFilesAndLinks(boolean found) {
+ checkOutput("testpkgmdl1/package-summary.html", found,
+ "<li><a href=\"../module1-summary.html\">Module</a></li>");
+ checkOutput("testpkgmdl1/package-summary.html", found,
+ "<div class=\"subTitle\"><span class=\"moduleLabelInClass\">Module</span> "
+ + "<a href=\"../module1-summary.html\">module1</a></div>");
+ checkOutput("testpkgmdl1/TestClassInModule1.html", found,
+ "<li><a href=\"../module1-summary.html\">Module</a></li>");
+ checkOutput("testpkgmdl1/TestClassInModule1.html", found,
+ "<div class=\"subTitle\"><span class=\"moduleLabelInClass\">Module</span> "
+ + "<a href=\"../module1-summary.html\">module1</a></div>");
+ checkFiles(found,
+ "module1-frame.html",
+ "module1-summary.html",
+ "module-overview-frame.html");
+ }
+
+ void checkModulesInSearch(boolean found) {
+ checkOutput("index-all.html", found,
+ "<dl>\n"
+ + "<dt><a href=\"module1-summary.html\">module1</a> - module module1</dt>\n"
+ + "<dd>\n"
+ + "<div class=\"block\">This is a test description for the module1 module.</div>\n"
+ + "</dd>\n"
+ + "<dt><a href=\"module2-summary.html\">module2</a> - module module2</dt>\n"
+ + "<dd>\n"
+ + "<div class=\"block\">This is a test description for the module2 module.</div>\n"
+ + "</dd>\n"
+ + "</dl>");
+ checkOutput("index-all.html", found,
+ "<dl>\n"
+ + "<dt><span class=\"searchTagLink\"><a href=\"module1-summary.html#searchphrase\">"
+ + "search phrase</a></span> - Search tag in module1</dt>\n"
+ + "<dd>with description</dd>\n"
+ + "<dt><span class=\"searchTagLink\"><a href=\"module2-summary.html#search_word\">"
+ + "search_word</a></span> - Search tag in module2</dt>\n"
+ + "<dd> </dd>\n"
+ + "</dl>");
}
+}
--- a/langtools/test/jdk/javadoc/doclet/testModules/module1/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module1/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,7 +24,7 @@
*/
/**
- * This is a test description for the module1 module.
+ * This is a test description for the module1 module. Search phrase {@index "search phrase" with description}.
*/
module module1 {
requires module2;
--- a/langtools/test/jdk/javadoc/doclet/testModules/module2/module-info.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module2/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -24,7 +24,7 @@
*/
/**
- * This is a test description for the module2 module.
+ * This is a test description for the module2 module. Search word {@index search_word} with no description.
*/
module module2 {
exports testpkgmdl2;
--- a/langtools/test/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java Mon Aug 29 08:53:32 2016 -0700
@@ -186,22 +186,22 @@
checkOutput("pkg/TypeParameters.html", true,
"<dl>\n"
+ "<dt>All Implemented Interfaces:</dt>\n"
- + "<dd><a href=\"../pkg/SubInterface.html\" title=\"interface in pkg\">"
- + "SubInterface</a><E>, <a href=\"../pkg/SuperInterface.html\" "
- + "title=\"interface in pkg\">SuperInterface</a><E></dd>\n"
+ + "<dd><code><a href=\"../pkg/SubInterface.html\" title=\"interface in pkg\">"
+ + "SubInterface</a><E></code>, <code><a href=\"../pkg/SuperInterface.html\" "
+ + "title=\"interface in pkg\">SuperInterface</a><E></code></dd>\n"
+ "</dl>");
checkOutput("pkg/SuperInterface.html", true,
"<dl>\n"
+ "<dt>All Known Subinterfaces:</dt>\n"
- + "<dd><a href=\"../pkg/SubInterface.html\" title=\"interface in pkg\">"
- + "SubInterface</a><V></dd>\n"
+ + "<dd><code><a href=\"../pkg/SubInterface.html\" title=\"interface in pkg\">"
+ + "SubInterface</a><V></code></dd>\n"
+ "</dl>");
checkOutput("pkg/SubInterface.html", true,
"<dl>\n"
+ "<dt>All Superinterfaces:</dt>\n"
- + "<dd><a href=\"../pkg/SuperInterface.html\" title=\"interface in pkg\">"
- + "SuperInterface</a><V></dd>\n"
+ + "<dd><code><a href=\"../pkg/SuperInterface.html\" title=\"interface in pkg\">"
+ + "SuperInterface</a><V></code></dd>\n"
+ "</dl>");
//==============================================================
--- a/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8039410 8042601 8042829 8049393 8050031 8155061
+ * @bug 8039410 8042601 8042829 8049393 8050031 8155061 8155995
* @summary test to determine if members are ordered correctly
* @author ksrini
* @library ../lib/
@@ -179,10 +179,27 @@
"something()</a></span> - Method in class a.<a href=\"a/something.html\"",
"something()</a></span> - Method in class something.<a href=\"something/J.html\""
};
+
String[] composeTestVectors() {
List<String> testList = new ArrayList<>();
testList.addAll(Arrays.asList(expectedPackageOrdering));
+ for (String x : expectedEnumOrdering) {
+ testList.add(x.replace("REPLACE_ME", "<Unnamed>"));
+ for (int i = 0; i < MAX_PACKAGES; i++) {
+ String wpkg = "add" + i;
+ testList.add(wpkg + "/" + x.replace("REPLACE_ME",
+ wpkg));
+ String dpkg = wpkg;
+ for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
+ dpkg = dpkg + "/" + "add";
+ testList.add(dpkg + "/" + x.replace("REPLACE_ME",
+ pathToPackage(dpkg)));
+ }
+ }
+ }
+
+ testList.addAll(Arrays.asList(expectedFieldOrdering));
for (String x : expectedMethodOrdering) {
testList.add(x);
@@ -197,21 +214,6 @@
}
}
- for (String x : expectedEnumOrdering) {
- testList.add(x.replace("REPLACE_ME", "<Unnamed>"));
- for (int i = 0; i < MAX_PACKAGES; i++) {
- String wpkg = "add" + i;
- testList.add(wpkg + "/" + x.replace("REPLACE_ME", wpkg));
- String dpkg = wpkg;
- for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
- dpkg = dpkg + "/" + "add";
- testList.add(dpkg + "/" + x.replace("REPLACE_ME", pathToPackage(dpkg)));
- }
- }
- }
-
- testList.addAll(Arrays.asList(expectedFieldOrdering));
-
return testList.toArray(new String[testList.size()]);
}
--- a/langtools/test/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java Mon Aug 29 08:53:32 2016 -0700
@@ -77,8 +77,8 @@
"<pre>public void methodInheritedFromParent(int p1)",
"<dl>\n"
+ "<dt>All Implemented Interfaces:</dt>\n"
- + "<dd><a href=\"../pkg/PublicInterface.html\" title=\"interface in pkg\">"
- + "PublicInterface</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/PublicInterface.html\" title=\"interface in pkg\">"
+ + "PublicInterface</a></code></dd>\n"
+ "</dl>");
checkOutput("pkg/PublicChild.html", false,
@@ -115,8 +115,8 @@
//Make sure implemented interfaces from private superclass are inherited
"<dl>\n"
+ "<dt>All Known Implementing Classes:</dt>\n"
- + "<dd><a href=\"../pkg/PublicChild.html\" title=\"class in pkg\">"
- + "PublicChild</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/PublicChild.html\" title=\"class in pkg\">"
+ + "PublicChild</a></code></dd>\n"
+ "</dl>");
checkOutput("pkg/PublicInterface.html", false,
@@ -178,10 +178,10 @@
"extends",
"<dl>\n"
+ "<dt>All Implemented Interfaces:</dt>\n"
- + "<dd><a href=\"../pkg/PrivateInterface.html\" title=\"interface in pkg\">"
- + "PrivateInterface</a>, "
- + "<a href=\"../pkg/PublicInterface.html\" title=\"interface in pkg\">"
- + "PublicInterface</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/PrivateInterface.html\" title=\"interface in pkg\">"
+ + "PrivateInterface</a></code>, "
+ + "<code><a href=\"../pkg/PublicInterface.html\" title=\"interface in pkg\">"
+ + "PublicInterface</a></code></dd>\n"
+ "</dl>",
"<pre>public class <span class=\"typeNameLabel\">PublicChild</span>");
@@ -202,10 +202,10 @@
//Make sure implemented interfaces from private superclass are inherited
"<dl>\n"
+ "<dt>All Known Implementing Classes:</dt>\n"
- + "<dd><a href=\"../pkg/PrivateParent.html\" title=\"class in pkg\">"
- + "PrivateParent</a>, "
- + "<a href=\"../pkg/PublicChild.html\" title=\"class in pkg\">PublicChild"
- + "</a></dd>\n"
+ + "<dd><code><a href=\"../pkg/PrivateParent.html\" title=\"class in pkg\">"
+ + "PrivateParent</a></code>, "
+ + "<code><a href=\"../pkg/PublicChild.html\" title=\"class in pkg\">PublicChild"
+ + "</a></code></dd>\n"
+ "</dl>");
checkOutput("pkg/PrivateInterface.html", true,
--- a/langtools/test/jdk/javadoc/tool/6227454/Test.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/6227454/Test.java Mon Aug 29 08:53:32 2016 -0700
@@ -140,9 +140,9 @@
public boolean run(DocletEnvironment root) {
DocTrees docTrees = root.getDocTrees();
- System.out.println("classes:" + root.getIncludedClasses());
+ System.out.println("classes:" + root.getIncludedTypeElements());
- Element klass = root.getIncludedClasses().iterator().next();
+ Element klass = root.getIncludedTypeElements().iterator().next();
String text = "";
try {
DocCommentTree dcTree = docTrees.getDocCommentTree(klass, overviewpath);
--- a/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java Mon Aug 29 08:53:32 2016 -0700
@@ -75,7 +75,7 @@
}
public boolean run(DocletEnvironment root) {
- TypeElement cd = root.getIncludedClasses().iterator().next();
+ TypeElement cd = root.getIncludedTypeElements().iterator().next();
VariableElement fd = getFields(cd).get(0);
DocTrees docTrees = root.getDocTrees();
DocCommentTree docCommentTree = docTrees.getDocCommentTree(fd);
--- a/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
public boolean run(DocletEnvironment root) {
DocTrees trees = root.getDocTrees();
- TypeElement cd = root.getIncludedClasses().iterator().next();
+ TypeElement cd = root.getIncludedTypeElements().iterator().next();
DocCommentTree docCommentTree = trees.getDocCommentTree(cd);
List<? extends DocTree> tags = docCommentTree.getBody();
--- a/langtools/test/jdk/javadoc/tool/NoStar.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/NoStar.java Mon Aug 29 08:53:32 2016 -0700
@@ -62,7 +62,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes));
TypeElement self = classes.iterator().next();
--- a/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java Mon Aug 29 08:53:32 2016 -0700
@@ -59,7 +59,7 @@
DocTrees trees = root.getDocTrees();
SourcePositions sourcePositions = trees.getSourcePositions();
- for (TypeElement klass : root.getIncludedClasses()) {
+ for (TypeElement klass : root.getIncludedTypeElements()) {
for (ExecutableElement method : getMethods(klass)) {
if (method.getSimpleName().toString().equals("tabbedMethod")) {
TreePath path = trees.getPath(method);
--- a/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java Mon Aug 29 08:53:32 2016 -0700
@@ -54,7 +54,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes));
return true;
--- a/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java Mon Aug 29 08:53:32 2016 -0700
@@ -48,7 +48,6 @@
String path1 = new File(srcFile, "sp1").getPath();
String path2 = new File(srcFile, "sp2").getPath();
String[] aargs = {
- "javadoc",
"-docletpath",
new File(System.getProperty("test.classes", ".")).getPath(),
"-doclet",
@@ -63,7 +62,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 2)
throw new Error("1 " + Arrays.asList(classes));
for (TypeElement clazz : classes) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8159305
+ * @summary Tests elements filtering options
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * jdk.javadoc/jdk.javadoc.internal.tool
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main FilterOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+
+public class FilterOptions extends ModuleTestBase {
+
+ private static final String NL = System.getProperty("line.separator");
+ private static final String INDENT = " ";
+
+ // the sources are shared, so create it once
+ private final String src;
+
+ public static void main(String... args) throws Exception {
+ new FilterOptions().runTests();
+ }
+
+ FilterOptions() throws IOException {
+ this.src = createSources(Paths.get(".").resolve("src"));
+ }
+
+ @Test
+ public void testDefault(Path base) throws Exception {
+ execTask("-modulesourcepath", src, "--module", "m1");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+ }
+
+ @Test
+ public void testModuleModeApi(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1", "--show-module-contents:api");
+
+ checkModuleMode("API");
+ }
+
+ @Test
+ public void testModuleModeAll(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1", "--show-module-contents:all");
+
+ checkModuleMode("ALL");
+ }
+
+ @Test
+ public void testShowPackagesExported(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-packages:exported"); // default
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+ }
+
+ @Test
+ public void testShowPackagesAll(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-packages:all");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub", "pro");
+
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
+ }
+
+ @Test
+ public void testShowTypesPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:private");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+ "pub.A.PublicNested",
+ "pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested");
+
+ }
+
+ @Test
+ public void testShowTypesPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:package");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested");
+
+ checkTypesNotIncluded(".*private.*");
+ }
+
+ @Test
+ public void testShowTypesProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:protected");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkTypesNotIncluded("pub.A.Nested", "pub.A.PrivateNested", "pub.B.Nested",
+ "pub.B.PrivateNested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested");
+ }
+
+ @Test
+ public void testShowTypesPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:public");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.PublicNested");
+ checkTypesNotIncluded("pub.A.Nested",
+ "pub.A.ProtectedNested", "pub.A.PrivateNested",
+ "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PrivateNested",
+ "pub.B.PublicNested");
+ }
+
+ @Test
+ public void testShowMembersPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:private");
+
+ checkMembers(Visibility.PRIVATE);
+ }
+
+ @Test
+ public void testShowMembersPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:package");
+
+ checkMembers(Visibility.PACKAGE);
+ }
+
+ @Test
+ public void testShowMembersProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:protected");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testShowMembersPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:public");
+
+ checkMembers(Visibility.PUBLIC);
+ }
+
+ @Test
+ public void testLegacyPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-public");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PUBLIC);
+ }
+
+ @Test
+ public void testLegacyDefault(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testLegacyProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-protected");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testLegacyPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-package");
+
+ checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesIncluded("pro");
+ checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
+ "pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
+ "pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
+
+ checkMembers(Visibility.PACKAGE);
+ }
+
+ @Test
+ public void testLegacyPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-private");
+
+ checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesIncluded("pro");
+ checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested",
+ "pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+ "pub.A.PublicNested",
+ "pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
+ "pro.B.PublicNested",
+ "pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
+ "pro.A.PublicNested");
+
+ checkMembers(Visibility.PRIVATE);
+ }
+
+ private static enum Visibility {
+ PRIVATE, PACKAGE, PROTECTED, PUBLIC;
+ }
+
+ void checkMembers(Visibility v) throws Exception {
+ checkMembersPresence(v);
+ checkMembersAbsence(v);
+ }
+
+ void checkMembersPresence(Visibility v) throws Exception {
+ switch (v) {
+ case PRIVATE:
+ checkMembersSelected("pub.A.privateFieldA",
+ "pub.A.PublicNested.privateFieldPublicNested",
+ "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+ case PACKAGE:
+ checkMembersSelected("pub.A.FieldA",
+ "pub.A.PublicNested.FieldPublicNested",
+ "pub.A.ProtectedNested.FieldProtectedNested");
+
+ case PROTECTED:
+ checkMembersSelected("pub.A.<init>",
+ "pub.A.protectedFieldA",
+ "pub.A.PublicNested.protectedFieldPublicNested",
+ "pub.A.ProtectedNested.<init>",
+ "pub.A.ProtectedNested.protectedFieldProtectedNested",
+ "pub.A.ProtectedNested.publicFieldProtectedNested");
+
+ case PUBLIC:
+ checkMembersSelected("pub.A.publicFieldA",
+ "pub.A.PublicNested.<init>",
+ "pub.A.PublicNested.publicFieldPublicNested");
+
+ break;
+ }
+ }
+
+ void checkMembersAbsence(Visibility v) throws Exception {
+ switch (v) {
+ case PUBLIC:
+ checkMembersNotSelected("pub.A.protectedFieldA",
+ "pub.A.PublicNested.protectedFieldPublicNested",
+ "pub.A.ProtectedNested.<init>",
+ "pub.A.ProtectedNested.protectedFieldProtectedNested");
+
+ case PROTECTED:
+ checkMembersNotSelected("pub.A.FieldA",
+ "pub.A.PublicNested.FieldPublicNested",
+ "pub.A.ProtectedNested.FieldProtectedNested");
+
+ case PACKAGE:
+ checkMembersNotSelected("pub.A.privateFieldA",
+ "pub.A.PublicNested.privateFieldPublicNested",
+ "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+ case PRIVATE:
+ break;
+ }
+ }
+
+ String createSources(Path src) throws IOException {
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .classes(createClass("pub", "A", true))
+ .classes(createClass("pub", "B", false))
+ .classes(createClass("pro", "A", true))
+ .classes(createClass("pro", "B", false))
+ .exports("pub")
+ .write(src);
+ return src.toString();
+ }
+
+ String createClass(String pkg, String name, boolean isPublic) {
+ StringBuilder sb = new StringBuilder("package ")
+ .append(pkg)
+ .append("; ")
+ .append(NL);
+ sb.append(" /** Klass ")
+ .append(name)
+ .append(" */")
+ .append(NL);
+ sb.append(isPublic ? "public " : " ")
+ .append("class ")
+ .append(name)
+ .append(" {")
+ .append(NL);
+
+ sb.append(createMembers(INDENT, name));
+ sb.append(createNestedClass(INDENT, "PublicNested", name, "public"));
+ sb.append(createNestedClass(INDENT, "ProtectedNested", name, "protected"));
+ sb.append(createNestedClass(INDENT, "Nested", name, ""));
+ sb.append(createNestedClass(INDENT, "PrivateNested", name, "private"));
+
+ return sb.append("}").toString();
+ }
+
+ StringBuilder createNestedClass(String indent, String name, String enclosing, String visibility) {
+ return new StringBuilder()
+ .append(indent).append(" /** Klass ").append(name).append(" */").append(NL)
+ .append(indent).append(visibility).append(" class ").append(name).append(" {").append(NL)
+ .append(createMembers(indent + INDENT, name)).append(indent).append("}").append(NL);
+ }
+
+ StringBuilder createMembers(String indent, String enclosing) {
+ return new StringBuilder()
+ .append(indent).append(createMember(enclosing, "public"))
+ .append(indent).append(createMember(enclosing, "protected"))
+ .append(indent).append(createMember(enclosing, ""))
+ .append(indent).append(createMember(enclosing, "private"))
+ .append(NL);
+ }
+
+ StringBuilder createMember(String enclosingClass, String visibility) {
+ return new StringBuilder()
+ .append("/** a ")
+ .append(visibility)
+ .append("Field in ")
+ .append(enclosingClass)
+ .append(" */ ")
+ .append(visibility)
+ .append(" String ")
+ .append(visibility)
+ .append("Field")
+ .append(enclosingClass)
+ .append(";")
+ .append(NL);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/ModuleTestBase.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+import static toolbox.Task.OutputKind.*;
+
+/**
+ * Base class for module tests.
+ */
+public class ModuleTestBase extends TestRunner {
+
+ // Field Separator
+ private static final String FS = " ";
+
+ protected ToolBox tb;
+ private final Class<?> docletClass;
+
+ private Task.Result currentTask = null;
+
+ ModuleTestBase() {
+ super(System.err);
+ tb = new ToolBox();
+ ClassLoader cl = ModuleTestBase.class.getClassLoader();
+ try {
+ docletClass = cl.loadClass("ModuleTestBase$ModulesTesterDoclet");
+ } catch (ClassNotFoundException cfe) {
+ throw new Error(cfe);
+ }
+ }
+
+ /**
+ * Execute methods annotated with @Test, and throw an exception if any
+ * errors are reported..
+ *
+ * @throws Exception if any errors occurred
+ */
+ protected void runTests() throws Exception {
+ runTests(m -> new Object[] { Paths.get(m.getName()) });
+ }
+
+ Task.Result execTask(String... args) {
+ return execTask0(false, args);
+ }
+
+ Task.Result execNegativeTask(String... args) {
+ return execTask0(true, args);
+ }
+
+ private Task.Result execTask0(boolean isNegative, String... args) {
+ JavadocTask et = new JavadocTask(tb, Task.Mode.API);
+ et.docletClass(docletClass);
+ //Arrays.asList(args).forEach((a -> System.err.println("arg: " + a)));
+ System.err.println(Arrays.asList(args));
+ currentTask = isNegative
+ ? et.options(args).run(Expect.FAIL)
+ : et.options(args).run();
+ return currentTask;
+ }
+
+ Path[] findHtmlFiles(Path... paths) throws IOException {
+ return tb.findFiles(".html", paths);
+ }
+
+ boolean grep(String regex, Path file) throws Exception {
+ List<String> lines = tb.readAllLines(file);
+ List<String> foundList = tb.grep(regex, lines);
+ return !foundList.isEmpty();
+ }
+
+ String normalize(String in) {
+ return in.replace('\\', '/');
+ }
+
+ void checkModulesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkModulesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkMembersSelected(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
+ }
+ }
+
+ void checkModuleMode(String mode) throws Exception {
+ assertPresent("^ModuleMode" + FS + mode);
+ }
+
+ void checkStringPresent(String regex) throws Exception {
+ assertPresent(regex);
+ }
+
+ void checkDocletOutputPresent(String category, ElementKind kind, String regex) throws Exception {
+ assertPresent("^" + category + " " + kind.toString() + " " + regex);
+ }
+
+ void assertPresent(String regex) throws Exception {
+ assertPresent(regex, STDOUT);
+ }
+
+ void assertErrorPresent(String regex) throws Exception {
+ assertPresent(regex, Task.OutputKind.DIRECT);
+ }
+
+ void assertPresent(String regex, Task.OutputKind kind) throws Exception {
+ List<String> foundList = tb.grep(regex, currentTask.getOutputLines(kind));
+ if (foundList.isEmpty()) {
+ dumpDocletDiagnostics();
+ throw new Exception(regex + " not found in: " + kind);
+ }
+ }
+
+ void dumpDocletDiagnostics() {
+ for (Task.OutputKind kind : Task.OutputKind.values()) {
+ String output = currentTask.getOutput(kind);
+ if (output != null && !output.isEmpty()) {
+ System.err.println("<" + kind + ">");
+ System.err.println(output);
+ }
+ }
+ }
+
+ void checkModulesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkModulesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkMembersNotSelected(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Selected", ElementKind.METHOD, arg);
+ }
+ }
+
+ void checkStringAbsent(String regex) throws Exception {
+ assertAbsent(regex);
+ }
+
+ void checkDocletOutputAbsent(String category, ElementKind kind, String regex) throws Exception {
+ assertAbsent("^" + category + FS + kind.toString() + FS + regex);
+ }
+
+ void assertAbsent(String regex) throws Exception {
+ List<String> foundList = tb.grep(regex, currentTask.getOutputLines(STDOUT));
+ if (!foundList.isEmpty()) {
+ dumpDocletDiagnostics();
+ throw new Exception(regex + " found in: " + STDOUT);
+ }
+ }
+
+ public static class ModulesTesterDoclet implements Doclet {
+ StringWriter sw = new StringWriter();
+ PrintWriter ps = new PrintWriter(sw);
+
+ // csv style output, for simple regex verification
+ void printDataSet(String header, Set<? extends Element> set) {
+ for (Element e : set) {
+ ps.print(header);
+ new SimpleElementVisitor9<Void, Void>() {
+ @Override
+ public Void visitModule(ModuleElement e, Void p) {
+ ps.print(FS);
+ ps.print(e.getKind());
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ public Void visitPackage(PackageElement e, Void p) {
+ ps.print(FS);
+ ps.print(e.getKind());
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ ps.print(FS);
+ ps.print(ElementKind.CLASS);
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ protected Void defaultAction(Element e, Void p) {
+ Element encl = e.getEnclosingElement();
+ CharSequence fqn = new SimpleElementVisitor9<CharSequence, Void>() {
+ @Override
+ public CharSequence visitModule(ModuleElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ @Override
+ public CharSequence visitType(TypeElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ @Override
+ public CharSequence visitPackage(PackageElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ }.visit(encl);
+
+ ps.print(FS);
+ ps.print(ElementKind.METHOD); // always METHOD
+ ps.print(FS);
+ ps.print(fqn);
+ ps.print(".");
+ ps.println(e.getSimpleName());
+ return null;
+ }
+ }.visit(e);
+ }
+ }
+
+ @Override
+ public boolean run(DocletEnvironment docenv) {
+ ps.println("ModuleMode" + FS + docenv.getModuleMode());
+ printDataSet("Specified", docenv.getSpecifiedElements());
+ printDataSet("Included", docenv.getIncludedModuleElements());
+ printDataSet("Included", docenv.getIncludedPackageElements());
+ printDataSet("Included", docenv.getIncludedTypeElements());
+ printDataSet("Selected", getAllSelectedElements(docenv));
+ System.out.println(sw);
+ return true;
+ }
+
+ Set<Element> getAllSelectedElements(DocletEnvironment docenv) {
+ Set<Element> result = new TreeSet<Element>((Element e1, Element e2) -> {
+ // some grouping by kind preferred
+ int rc = e1.getKind().compareTo(e2.getKind());
+ if (rc != 0) return rc;
+ rc = e1.toString().compareTo(e2.toString());
+ if (rc != 0) return rc;
+ return Integer.compare(e1.hashCode(), e2.hashCode());
+ });
+ for (ModuleElement me : docenv.getIncludedModuleElements()) {
+ addEnclosedElements(docenv, result, me);
+ }
+ for (PackageElement pe : docenv.getIncludedPackageElements()) {
+ addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
+ addEnclosedElements(docenv, result, pe);
+ }
+ for (TypeElement te : docenv.getIncludedTypeElements()) {
+ addEnclosedElements(docenv, result, te);
+ }
+ return result;
+ }
+
+ void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) {
+ List<? extends Element> elems = docenv.getSelectedElements(e.getEnclosedElements());
+ result.addAll(elems);
+ for (TypeElement t : ElementFilter.typesIn(elems)) {
+ addEnclosedElements(docenv, result, t);
+ }
+ }
+
+ @Override
+ public Set<Doclet.Option> getSupportedOptions() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void init(Locale locale, Reporter reporter) {}
+
+ @Override
+ public String getName() {
+ return "ModulesTesterDoclet";
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8159305
+ * @summary Tests primarily the module graph computations.
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * jdk.javadoc/jdk.javadoc.internal.tool
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main Modules
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class Modules extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new Modules().runTests();
+ }
+
+ @Test
+ public void testBasicMoption(Path base) throws Exception {
+ Files.createDirectory(base);
+ Path src = base.resolve("src");
+ ModuleBuilder mb = new ModuleBuilder(tb, "m1");
+ mb.comment("The first module.")
+ .exports("pub")
+ .classes("package pub; /** Klass A */ public class A {}")
+ .classes("package pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1");
+ checkModulesSpecified("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A");
+ }
+
+ @Test
+ public void testMultipleModulesOption1(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .exports("m1pub")
+ .requires("m2")
+ .classes("package m1pub; /** Klass A */ public class A {}")
+ .classes("package m1pro; /** Klass B */ public class B {}")
+ .write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module.")
+ .exports("m2pub")
+ .classes("package m2pub; /** Klass A */ public class A {}")
+ .classes("package m2pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1,m2");
+ checkModulesSpecified("m1", "m2");
+ checkPackagesIncluded("m1pub", "m2pub");
+ checkTypesIncluded("m1pub.A", "m2pub.A");
+
+ }
+
+ @Test
+ public void testMultipleModulesAggregatedModuleOption(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .exports("m1pub")
+ .requires("m2")
+ .classes("package m1pub; /** Klass A */ public class A {}")
+ .classes("package m1pro; /** Klass B */ public class B {}")
+ .write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module.")
+ .exports("m2pub")
+ .classes("package m2pub; /** Klass A */ public class A {}")
+ .classes("package m2pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1",
+ "--module", "m2");
+ checkModulesSpecified("m1", "m2");
+ checkPackagesIncluded("m1pub", "m2pub");
+ checkTypesIncluded("m1pub.A", "m2pub.A");
+
+ }
+
+ /**
+ * Tests diamond graph, inspired by javac diamond tests.
+ *
+ *
+ * Module M : test module, with variable requires
+ *
+ * Module N :
+ * requires public O ---> Module O:
+ * requires J ----> Module J:
+ * exports openO exports openJ
+ *
+ *
+ * Module L :
+ * requires public P ---> Module P:
+ * exports openP
+ *
+ *
+ */
+
+ @Test
+ public void testExpandRequiresNone(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requires("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M");
+
+ checkModulesSpecified("M");
+ checkModulesIncluded("M");
+ checkPackagesIncluded("p");
+ checkTypesIncluded("p.Main");
+ checkPackagesNotIncluded(".*open.*");
+ }
+
+ @Test
+ public void testExpandRequiresPublic(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M",
+ "--expand-requires:public");
+
+ checkModulesSpecified("M", "N", "O");
+ checkModulesIncluded("M", "N", "O");
+ checkPackagesIncluded("p", "openN", "openO");
+ checkTypesIncluded("p.Main", "openN.N", "openO.O");
+ }
+
+ @Test
+ public void testExpandRequiresAll(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M",
+ "--expand-requires:all");
+
+ checkModulesSpecified("M", "java.base", "N", "L", "O");
+ checkModulesIncluded("M", "java.base", "N", "L", "O");
+ checkModulesNotIncluded("P", "J", "Q");
+ checkPackagesIncluded("p", "openN", "openL", "openO");
+ checkPackagesNotIncluded(".*openP.*", ".*openJ.*");
+ checkTypesIncluded("p.Main", "openN.N", "openL.L", "openO.O");
+ checkTypesNotIncluded(".*openP.*", ".*openJ.*");
+ }
+
+ @Test
+ public void testMissingModule(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "--module", "MIA",
+ "--expand-requires:all");
+
+ assertErrorPresent("javadoc: error - module MIA not found.");
+ }
+
+ @Test
+ public void testMissingModuleMultiModuleCmdline(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "--module", "M,N,L,MIA,O,P",
+ "--expand-requires:all");
+
+ assertErrorPresent("javadoc: error - module MIA not found");
+ }
+
+ void createAuxiliaryModules(Path src) throws IOException {
+
+ new ModuleBuilder(tb, "J")
+ .comment("The J module.")
+ .exports("openJ")
+ .classes("package openJ; /** Klass J open. */ public class J { }")
+ .classes("package closedJ; /** Klass J closed. */ public class J { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "L")
+ .comment("The L module.")
+ .exports("openL")
+ .requiresPublic("P")
+ .classes("package openL; /** Klass L open */ public class L { }")
+ .classes("package closedL; /** Klass L closed */ public class L { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "N")
+ .comment("The N module.")
+ .exports("openN")
+ .requiresPublic("O")
+ .classes("package openN; /** Klass N open */ public class N { }")
+ .classes("package closedN; /** Klass N closed */ public class N { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "O")
+ .comment("The O module.")
+ .exports("openO")
+ .requires("J")
+ .classes("package openO; /** Klass O open. */ public class O { openJ.J j; }")
+ .classes("package closedO; /** Klass O closed. */ public class O { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "P")
+ .comment("The O module.")
+ .exports("openP")
+ .requires("J")
+ .classes("package openP; /** Klass O open. */ public class O { openJ.J j; }")
+ .classes("package closedP; /** Klass O closed. */ public class O { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "Q")
+ .comment("The Q module.")
+ .exports("openQ")
+ .requires("J")
+ .classes("package openQ; /** Klass Q open. */ public class Q { openJ.J j; }")
+ .classes("package closedQ; /** Klass Q closed. */ public class Q { }")
+ .write(src);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8159305
+ * @summary Test modules with packages and subpackages filtering
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * jdk.javadoc/jdk.javadoc.internal.tool
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main PackageOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class PackageOptions extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new PackageOptions().runTests();
+ }
+
+ @Test
+ public void testExportedNonQualifiedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1pub");
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pub");
+ checkPackagesIncluded("m1pub");
+ }
+
+ @Test
+ public void testExportedQualifiedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1/m1pub");
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pub");
+ checkPackagesIncluded("m1pub");
+ }
+
+ @Test
+ public void testNonExportedQualifedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1/m1pro.pro1" /* not exported, therefore qualify with module */);
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pro.pro1");
+ checkPackagesIncluded("m1pro.pro1");
+ checkPackagesNotIncluded("m1pro.pro2");
+ checkPackagesNotIncluded("m1pub");
+ }
+
+ @Test
+ public void testTypesLegacyMode(Path base) throws Exception {
+ Path srcPath = base.resolve("src");
+ Path typPath = srcPath.resolve("m1/m1pub/A.java");
+ execTask("-modulesourcepath", createSources(srcPath),
+ "-addmods", "m1",
+ typPath.toString());
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("m1pub");
+ checkPackagesNotIncluded("m1pro");
+ checkTypesSpecified("m1pub.A");
+ checkTypesIncluded("m1pub.A");
+ checkTypesNotIncluded("m1pub.B");
+ checkTypesNotIncluded("m1pub.C");
+ }
+
+ @Test
+ public void testSubclassedTypesLegacyMode(Path base) throws Exception {
+ Path srcPath = base.resolve("src");
+ Path typPath = srcPath.resolve("m1/m1pub/B.java");
+ execTask("-modulesourcepath", createSources(srcPath),
+ "-addmods", "m1",
+ typPath.toString());
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("m1pub");
+ checkPackagesNotIncluded("m1pro");
+ checkTypesSpecified("m1pub.B");
+ checkTypesIncluded("m1pub.B");
+ checkTypesNotIncluded("m1pub.A");
+ checkTypesNotIncluded("m1pub.C");
+ }
+
+ @Test
+ public void testDefaultPackages(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1");
+
+ checkModulesSpecified("m1");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ }
+
+ @Test
+ public void testEmptyPackageDirectory(Path base) throws Exception {
+ Path src = base.resolve("src");
+ createSources(src);
+
+ // need an empty package directory, to check whether
+ // the behavior of subpackage and package
+ Path pkgdir = src.resolve("m1/m1pro/");
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(pkgdir, "*.java")) {
+ for (Path entry : stream) {
+ Files.deleteIfExists(entry);
+ }
+ } catch (DirectoryIteratorException ex) {
+ // I/O error encounted during the iteration
+ throw ex.getCause();
+ }
+ execTask("-modulesourcepath", src.toString(),
+ "-subpackages", "m1/m1pro");
+
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ // empty package directory should cause an error
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "m1/m1pro");
+
+ }
+
+ @Test
+ public void testExportedQualifiedSubpackageWithMultipleModules(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src"), 2),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2:m2/m2pub.pub1");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro2");
+ checkPackagesSpecified("m2pub.pub1");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ checkPackagesIncluded("m2pub.pub1");
+ }
+
+ @Test
+ public void testUnexportedUnqualifiedSubpackages(Path base) throws Exception {
+ execNegativeTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1pub.pub1:pro");
+
+ assertErrorPresent("javadoc: error - No source files for package pro");
+ }
+
+ @Test
+ public void testUnexportedQualifiedPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "m1/m1pro");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackage(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackageExcludeQualified(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro",
+ "-exclude", "m1/m1pro.pro1.pro11:m1/m1pro.pro2.pro21");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackageExcludeUnqualified(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro",
+ "-exclude", "m1pro.pro1.pro11:m1pro.pro2.pro21");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackages(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro.pro1.pro11");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ checkTypesIncluded("m1pro.pro1.pro11.N", "m1pro.pro2.pro21.P");
+ checkTypesNotIncluded("m1pro.L");
+ }
+
+ String createSources(Path src) throws IOException {
+ return createSources0(src, 1);
+ }
+
+ String createSources(Path src, int n) throws IOException {
+ for (int i = 1 ; i <= n ; i++) {
+ createSources0(src, i);
+ }
+ return src.toString();
+ }
+
+ String createSources0(Path src, int n) throws IOException {
+ String mn = "m" + n;
+ String pn = "package " + mn;
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, mn);
+ mb1.comment("The module #" + n)
+ .classes(pn + "pub; /** Klass A */ public class A {}")
+ .classes(pn + "pub; /** Klass B */ public class B extends A{}")
+ .classes(pn + "pub; /** Klass C */ public class C {}")
+ .classes(pn + "pub;")
+ .classes(pn + "pub.pub1; /** Klass B */ public class B {}")
+ .classes(pn + "pub.pub1.pub11; /** Klass C */ public class C {}")
+ .classes(pn + "pub.pub1.pub12; /** Klass C */ public class C {}")
+ .classes(pn + "pub.pub2.pub21; /** Klass C */ public class C {}")
+ .classes(pn + "pro; /** Klass L */ public class L {}")
+ .classes(pn + "pro.pro1; /** Klass M */ public class M {}")
+ .classes(pn + "pro.pro1.pro11; /** Klass N */ public class N {}")
+ .classes(pn + "pro.pro2; /** Klass O */ public class O {}")
+ .classes(pn + "pro.pro2.pro21; /** Klass P */ public class P {}")
+ .exports(mn + "pub")
+ .exports(mn + "pub.pub1")
+ .exports(mn + "pub.pub1.pub11")
+ .exports(mn + "pub.pub1.pub12")
+ .exports(mn + "pub.pub2.pub21")
+ .write(src);
+ return src.toString();
+ }
+}
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java Mon Aug 29 08:53:32 2016 -0700
@@ -34,7 +34,12 @@
public class Test {
public static void main(String[] args) {
// run javadoc on package p
- if (jdk.javadoc.internal.tool.Main.execute("javadoc", "p.SourceOnly", "p") != 0)
+ String[] jdargs = {
+ "-doclet", "p.SourceOnly",
+ "-docletpath", System.getProperty("test.classes", "."),
+ "p"
+ };
+ if (jdk.javadoc.internal.tool.Main.execute(jdargs) != 0)
throw new Error();
}
}
Binary file langtools/test/jdk/javadoc/tool/sourceOnly/p/NonSource.class has changed
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java Mon Aug 29 08:53:32 2016 -0700
@@ -39,11 +39,12 @@
*/
public class SourceOnly implements Doclet {
NonSource dependency; // force a compilation error if not on classpath.
+
@Override
public boolean run(DocletEnvironment root) {
- if (root.getIncludedClasses().size() != 1)
+ if (root.getIncludedTypeElements().size() != 1)
throw new Error("wrong set of classes documented: " +
- Arrays.asList(root.getIncludedClasses()));
+ Arrays.asList(root.getIncludedTypeElements()));
return true;
}
--- a/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java Mon Aug 29 08:53:32 2016 -0700
@@ -92,7 +92,7 @@
}
public boolean run(DocletEnvironment root) {
- root.getIncludedClasses(); // force parser into action
+ root.getIncludedTypeElements();
return true;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/subpackageIgnore/pkg1/ValidFile.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package pkg1;
+
+/**
+ * This file exists simply to ensure that javadoc passes
+ * without complaining about empty directory.
+ */
+public class ValidFile {}
--- a/langtools/test/jdk/jshell/CompletenessStressTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/CompletenessStressTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -253,10 +253,8 @@
writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
start, end, unit));
} else {
- String oops = unit.substring(max(0, ci.unitEndPos() - 10), ci.unitEndPos()) + "|||" +
- unit.substring(ci.unitEndPos(), min(unit.length(), ci.unitEndPos() + 10));
writer.write(String.format("Expected %s got %s: '%s' row %d, column %d: -- %s\n",
- expected, ci.completeness(), oops, row, column, unit));
+ expected, ci.completeness(), unit, row, column, unit));
return false;
}
}
--- a/langtools/test/jdk/jshell/JShellQueryTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/JShellQueryTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -28,8 +28,6 @@
* @build KullaTesting
* @run testng JShellQueryTest
*/
-import java.util.Set;
-import java.util.stream.Stream;
import jdk.jshell.Snippet;
import org.testng.annotations.Test;
@@ -38,46 +36,39 @@
import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toSet;
import static org.testng.Assert.assertEquals;
@Test
public class JShellQueryTest extends KullaTesting {
- private <T> void checkStreamMatch(Stream<T> result, T... expected) {
- Set<T> sns = result.collect(toSet());
- Set<T> exp = Stream.of(expected).collect(toSet());
- assertEquals(sns, exp);
- }
-
public void testSnippets() {
- checkStreamMatch(getState().snippets());
+ assertStreamMatch(getState().snippets());
VarSnippet sx = varKey(assertEval("int x = 5;"));
VarSnippet sfoo = varKey(assertEval("String foo;"));
MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
MethodSnippet svv = methodKey(assertEval("void vv() { }"));
- checkStreamMatch(getState().snippets(), sx, sfoo, smm, svv);
+ assertStreamMatch(getState().snippets(), sx, sfoo, smm, svv);
TypeDeclSnippet sc = classKey(assertEval("class C { }"));
TypeDeclSnippet si = classKey(assertEval("interface I { }"));
ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
- checkStreamMatch(getState().snippets(), sx, sfoo, smm, svv, sc, si, simp);
+ assertStreamMatch(getState().snippets(), sx, sfoo, smm, svv, sc, si, simp);
}
public void testVars() {
- checkStreamMatch(getState().variables());
+ assertStreamMatch(getState().variables());
VarSnippet sx = varKey(assertEval("int x = 5;"));
VarSnippet sfoo = varKey(assertEval("String foo;"));
MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
MethodSnippet svv = methodKey(assertEval("void vv() { }"));
- checkStreamMatch(getState().variables(), sx, sfoo);
+ assertStreamMatch(getState().variables(), sx, sfoo);
TypeDeclSnippet sc = classKey(assertEval("class C { }"));
TypeDeclSnippet si = classKey(assertEval("interface I { }"));
ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
- checkStreamMatch(getState().variables(), sx, sfoo);
+ assertStreamMatch(getState().variables(), sx, sfoo);
}
public void testMethods() {
- checkStreamMatch(getState().methods());
+ assertStreamMatch(getState().methods());
VarSnippet sx = varKey(assertEval("int x = 5;"));
VarSnippet sfoo = varKey(assertEval("String foo;"));
MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
@@ -85,11 +76,11 @@
TypeDeclSnippet sc = classKey(assertEval("class C { }"));
TypeDeclSnippet si = classKey(assertEval("interface I { }"));
ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
- checkStreamMatch(getState().methods(), smm, svv);
+ assertStreamMatch(getState().methods(), smm, svv);
}
public void testTypes() {
- checkStreamMatch(getState().types());
+ assertStreamMatch(getState().types());
VarSnippet sx = varKey(assertEval("int x = 5;"));
VarSnippet sfoo = varKey(assertEval("String foo;"));
MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
@@ -97,11 +88,11 @@
TypeDeclSnippet sc = classKey(assertEval("class C { }"));
TypeDeclSnippet si = classKey(assertEval("interface I { }"));
ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
- checkStreamMatch(getState().types(), sc, si);
+ assertStreamMatch(getState().types(), sc, si);
}
public void testImports() {
- checkStreamMatch(getState().imports());
+ assertStreamMatch(getState().imports());
VarSnippet sx = varKey(assertEval("int x = 5;"));
VarSnippet sfoo = varKey(assertEval("String foo;"));
MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
@@ -109,12 +100,12 @@
TypeDeclSnippet sc = classKey(assertEval("class C { }"));
TypeDeclSnippet si = classKey(assertEval("interface I { }"));
ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
- checkStreamMatch(getState().imports(), simp);
+ assertStreamMatch(getState().imports(), simp);
}
public void testDiagnostics() {
Snippet sx = varKey(assertEval("int x = 5;"));
- checkStreamMatch(getState().diagnostics(sx));
+ assertStreamMatch(getState().diagnostics(sx));
Snippet broken = methodKey(assertEvalFail("int m() { blah(); return \"hello\"; }"));
String res = getState().diagnostics(broken)
.map(d -> d.getCode())
@@ -124,8 +115,8 @@
public void testUnresolvedDependencies() {
VarSnippet sx = varKey(assertEval("int x = 5;"));
- checkStreamMatch(getState().unresolvedDependencies(sx));
+ assertStreamMatch(getState().unresolvedDependencies(sx));
MethodSnippet unr = methodKey(getState().eval("void uu() { baz(); zips(); }"));
- checkStreamMatch(getState().unresolvedDependencies(unr), "method zips()", "method baz()");
+ assertStreamMatch(getState().unresolvedDependencies(unr), "method zips()", "method baz()");
}
}
--- a/langtools/test/jdk/jshell/JShellStateClosedTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/JShellStateClosedTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -22,7 +22,7 @@
*/
/*
- * @test
+ * @test 8164277
* @summary Testing IllegalStateException.
* @build KullaTesting TestingInputStream JShellStateClosedTest
* @run testng JShellStateClosedTest
@@ -31,8 +31,11 @@
import java.util.function.Consumer;
import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.ImportSnippet;
+import jdk.jshell.MethodSnippet;
import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
+import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
@@ -52,19 +55,42 @@
}
public void testClasses() {
- testStateClosedException(() -> getState().types());
+ TypeDeclSnippet sc = classKey(assertEval("class C { }"));
+ TypeDeclSnippet si = classKey(assertEval("interface I { }"));
+ getState().close();
+ assertStreamMatch(getState().types(), sc, si);
}
public void testVariables() {
- testStateClosedException(() -> getState().variables());
+ VarSnippet sx = varKey(assertEval("int x = 5;"));
+ VarSnippet sfoo = varKey(assertEval("String foo;"));
+ getState().close();
+ assertStreamMatch(getState().variables(), sx, sfoo);
}
public void testMethods() {
- testStateClosedException(() -> getState().methods());
+ MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
+ MethodSnippet svv = methodKey(assertEval("void vv() { }"));
+ getState().close();
+ assertStreamMatch(getState().methods(), smm, svv);
}
- public void testKeys() {
- testStateClosedException(() -> getState().snippets());
+ public void testImports() {
+ ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
+ getState().close();
+ assertStreamMatch(getState().imports(), simp);
+ }
+
+ public void testSnippets() {
+ VarSnippet sx = varKey(assertEval("int x = 5;"));
+ VarSnippet sfoo = varKey(assertEval("String foo;"));
+ MethodSnippet smm = methodKey(assertEval("int mm() { return 6; }"));
+ MethodSnippet svv = methodKey(assertEval("void vv() { }"));
+ TypeDeclSnippet sc = classKey(assertEval("class C { }"));
+ TypeDeclSnippet si = classKey(assertEval("interface I { }"));
+ ImportSnippet simp = importKey(assertEval("import java.lang.reflect.*;"));
+ getState().close();
+ assertStreamMatch(getState().snippets(), sx, sfoo, smm, svv, sc, si, simp);
}
public void testEval() {
--- a/langtools/test/jdk/jshell/KullaTesting.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/KullaTesting.java Mon Aug 29 08:53:32 2016 -0700
@@ -71,6 +71,7 @@
import jdk.jshell.Diag;
import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
import static jdk.jshell.Snippet.Status.*;
import static org.testng.Assert.*;
import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND;
@@ -358,6 +359,12 @@
return checkEvents(() -> getState().eval(input), "eval(" + input + ")", diagMain, diagUpdates, eventChains);
}
+ <T> void assertStreamMatch(Stream<T> result, T... expected) {
+ Set<T> sns = result.collect(toSet());
+ Set<T> exp = Stream.of(expected).collect(toSet());
+ assertEquals(sns, exp);
+ }
+
private Map<Snippet, Snippet> closure(List<SnippetEvent> events) {
Map<Snippet, Snippet> transitions = new HashMap<>();
for (SnippetEvent event : events) {
--- a/langtools/test/jdk/jshell/SimpleRegressionTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/SimpleRegressionTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -22,7 +22,7 @@
*/
/*
- * @test 8130450
+ * @test 8130450 8158906 8154374
* @summary simple regression test
* @build KullaTesting TestingInputStream
* @run testng SimpleRegressionTest
@@ -39,6 +39,8 @@
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
import static jdk.jshell.Snippet.SubKind.TEMP_VAR_EXPRESSION_SUBKIND;
import static jdk.jshell.Snippet.Status.VALID;
@@ -100,6 +102,37 @@
assertEquals(sne.typeName(), "Integer");
}
+ public void testLongRemoteStrings() { //8158906
+ assertEval("String m(int x) { byte[] b = new byte[x]; for (int i = 0; i < x; ++i) b[i] = (byte) 'a'; return new String(b); }");
+ boolean[] shut = new boolean[1];
+ getState().onShutdown(j -> {
+ shut[0] = true;
+ });
+ for (String len : new String[]{"12345", "64000", "65535", "65536", "120000"}) {
+ List<SnippetEvent> el = assertEval("m(" + len + ");");
+ assertFalse(shut[0], "JShell died with long string");
+ assertEquals(el.size(), 1, "Excepted one event");
+ assertTrue(el.get(0).value().length() > 10000,
+ "Expected truncated but long String, got: " + el.get(0).value().length());
+ }
+ }
+
+ public void testLongRemoteJapaneseStrings() { //8158906
+ assertEval("import java.util.stream.*;");
+ assertEval("String m(int x) { return Stream.generate(() -> \"\u3042\").limit(x).collect(Collectors.joining()); }");
+ boolean[] shut = new boolean[1];
+ getState().onShutdown(j -> {
+ shut[0] = true;
+ });
+ for (String len : new String[]{"12345", "21843", "21844", "21845", "21846", "64000", "65535", "65536", "120000"}) {
+ List<SnippetEvent> el = assertEval("m(" + len + ");");
+ assertFalse(shut[0], "JShell died with long string");
+ assertEquals(el.size(), 1, "Excepted one event");
+ assertTrue(el.get(0).value().length() > 10000,
+ "Expected truncated but long String, got: " + el.get(0).value().length());
+ }
+ }
+
// 8130450
public void testDuplicate() {
Snippet snm = methodKey(assertEval("void mm() {}", added(VALID)));
@@ -111,4 +144,9 @@
ste(MAIN_SNIPPET, VALID, VALID, false, null),
ste(snv, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
}
+
+ public void testContextClassLoader() {
+ assertEval("class C {}");
+ assertEval("C.class.getClassLoader() == Thread.currentThread().getContextClassLoader()", "true");
+ }
}
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953
+ * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347
* @summary Tests for Basic tests for REPL tool
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -542,6 +542,13 @@
}
}
+ public void testVarsWithNotActive() {
+ test(
+ a -> assertVariable(a, "Blath", "x"),
+ a -> assertCommandOutputContains(a, "/var -all", "(not-active)")
+ );
+ }
+
public void testHistoryReference() {
test(false, new String[]{"-nostartup"},
a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/moduleTests/bad/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8162576
+ * @summary Missing doclint check missing for modules
+ * @library ../..
+ * @modules jdk.compiler/com.sun.tools.doclint
+ * @build DocLintTester
+ * @run main DocLintTester -ref module-info.out module-info.java
+ * @compile/fail/ref=module-info.javac.out -XDrawDiagnostics -Werror -Xdoclint:all module-info.java
+ */
+
+// missing doc comment
+module bad {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/moduleTests/bad/module-info.javac.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+module-info.java:13:1: compiler.warn.proc.messager: no comment
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/moduleTests/bad/module-info.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+module-info.java:13: warning: no comment
+module bad {
+^
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/moduleTests/good/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8162576
+ * @summary Missing doclint check missing for modules
+ * @library ../..
+ * @modules jdk.compiler/com.sun.tools.doclint
+ * @build DocLintTester
+ * @run main DocLintTester module-info.java
+ * @compile -Xdoclint:all -Werror module-info.java
+ */
+
+/** good module */
+module good {
+}
--- a/langtools/test/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Mon Aug 29 08:53:32 2016 -0700
@@ -2,5 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
BadlyTypedLabel1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6
-1 error
+BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
+2 errors
3 warnings
--- a/langtools/test/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Mon Aug 29 08:53:32 2016 -0700
@@ -2,6 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
BadlyTypedLabel2.java:12:15: compiler.err.string.switch.not.supported.in.source: 1.6
-BadlyTypedLabel2.java:15:14: compiler.err.const.expr.req
+BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.math.RoundingMode, java.lang.String)
2 errors
3 warnings
--- a/langtools/test/tools/javac/StringsInSwitch/NonConstantLabel6.out Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/StringsInSwitch/NonConstantLabel6.out Mon Aug 29 08:53:32 2016 -0700
@@ -2,6 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
NonConstantLabel.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6
-NonConstantLabel.java:14:14: compiler.err.const.expr.req
+NonConstantLabel.java:14:14: compiler.err.string.const.req
2 errors
3 warnings
--- a/langtools/test/tools/javac/StringsInSwitch/OneCaseSwitches.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/StringsInSwitch/OneCaseSwitches.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 6827009
+ * @bug 6827009 8078561
* @summary Positive tests for strings in switch with few alternatives.
* @compile/fail/ref=OneCaseSwitches.out -XDrawDiagnostics -source 6 OneCaseSwitches.java
* @compile OneCaseSwitches.java
--- a/langtools/test/tools/javac/StringsInSwitch/OneCaseSwitches.out Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/StringsInSwitch/OneCaseSwitches.out Mon Aug 29 08:53:32 2016 -0700
@@ -2,13 +2,5 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
OneCaseSwitches.java:23:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:33:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:52:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:66:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:85:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:99:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:119:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:130:15: compiler.err.string.switch.not.supported.in.source: 1.6
-OneCaseSwitches.java:242:16: compiler.err.string.switch.not.supported.in.source: 1.6
-9 errors
-3 warnings
+1 error
+3 warnings
\ No newline at end of file
--- a/langtools/test/tools/javac/defaultMethods/static/StaticInvoke.java Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-/* @test /nodynamiccopyright/
- * @bug 8037385
- * @summary Must not allow static interface method invocation in legacy code
- * @compile -source 8 -Xlint:-options StaticInvoke.java
- * @compile/fail/ref=StaticInvoke7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
- * @compile/fail/ref=StaticInvoke6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
- */
-import java.util.stream.Stream;
-
-class StaticInvoke {
- void test() {
- Stream.empty();
- java.util.stream.Stream.empty();
- }
-}
--- a/langtools/test/tools/javac/defaultMethods/static/StaticInvoke6.out Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
-StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
-2 errors
--- a/langtools/test/tools/javac/defaultMethods/static/StaticInvoke7.out Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
-StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
-2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeQualified.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,13 @@
+/* @test /nodynamiccopyright/
+ * @bug 8037385
+ * @summary Must not allow static interface method invocation in legacy code
+ * @compile -source 8 -Xlint:-options StaticInvokeQualified.java
+ * @compile/fail/ref=StaticInvokeQualified7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvokeQualified.java
+ * @compile/fail/ref=StaticInvokeQualified6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvokeQualified.java
+ */
+
+class StaticInvokeQualified {
+ void test() {
+ java.util.stream.Stream.empty();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeQualified6.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,2 @@
+StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeQualified7.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,2 @@
+StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeSimple.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,14 @@
+/* @test /nodynamiccopyright/
+ * @bug 8037385
+ * @summary Must not allow static interface method invocation in legacy code
+ * @compile -source 8 -Xlint:-options StaticInvokeSimple.java
+ * @compile/fail/ref=StaticInvokeSimple7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvokeSimple.java
+ * @compile/fail/ref=StaticInvokeSimple6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvokeSimple.java
+ */
+import java.util.stream.Stream;
+
+class StaticInvokeSimple {
+ void test() {
+ Stream.empty();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeSimple6.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,2 @@
+StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/StaticInvokeSimple7.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,2 @@
+StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
+1 error
\ No newline at end of file
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Mon Aug 29 08:53:32 2016 -0700
@@ -102,6 +102,7 @@
compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
compiler.warn.unexpected.archive.file # Paths: zip file with unknown extn
+compiler.err.no.zipfs.for.archive # would need zip/jar file
compiler.warn.unknown.enum.constant # in bad class file
compiler.warn.unknown.enum.constant.reason # in bad class file
compiler.warn.override.equals.but.not.hashcode # when a class overrides equals but not hashCode method from Object
@@ -117,6 +118,7 @@
compiler.warn.outdir.is.in.exploded.module # No control over -d specified by test infrastructure
compiler.err.invalid.module.specifier # Not possible (?)
compiler.err.locn.cant.get.module.name.for.jar # bad binary ? Infer module name failure
+compiler.misc.anachronistic.module.info # requires binaries compiled with EA compilers.
compiler.misc.bad.module-info.name # bad class file
compiler.err.locn.bad.module-info # bad class file
compiler.err.locn.cant.read.file # bad class file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InvalidModuleDirective/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.module.directive
+
+module java.transaction {
+ requires java.base;
+ resuires javax.interceptor.javax.interceptor.api;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/file/LimitedImage.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8153391
+ * @summary Verify javac behaves properly in absence of zip/jar FileSystemProvider
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @run main/othervm -limitmods jdk.compiler LimitedImage
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import toolbox.JavacTask;
+import toolbox.JarTask;
+import toolbox.Task.Expect;
+import toolbox.Task.Mode;
+import toolbox.Task.OutputKind;
+import toolbox.ToolBox;
+
+public class LimitedImage {
+ public static void main(String... args) throws IOException {
+ ToolBox tb = new ToolBox();
+
+ //showing help should be OK
+ new JavacTask(tb, Mode.CMDLINE)
+ .options("--help")
+ .run().writeAll();
+
+ Path testSource = Paths.get("Test.java");
+ tb.writeFile(testSource, "class Test {}");
+
+ //when zip/jar FS is not needed, compilation should succeed
+ new JavacTask(tb, Mode.CMDLINE)
+ .classpath()
+ .files(testSource)
+ .outdir(".")
+ .run()
+ .writeAll();
+
+ Path testJar = Paths.get("test.jar").toAbsolutePath();
+
+ new JarTask(tb, testJar).run();
+
+ List<String> actualOutput;
+ List<String> expectedOutput = Arrays.asList(
+ "- compiler.err.no.zipfs.for.archive: " + testJar.toString()
+ );
+
+ //check proper diagnostics when zip/jar FS not present:
+ actualOutput = new JavacTask(tb, Mode.CMDLINE)
+ .classpath(testJar)
+ .options("-XDrawDiagnostics")
+ .files(testSource)
+ .outdir(".")
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ if (!expectedOutput.equals(actualOutput)) {
+ throw new AssertionError("Unexpected output: " + actualOutput);
+ }
+
+ actualOutput = new JavacTask(tb, Mode.CMDLINE)
+ .sourcepath(testJar)
+ .options("-XDrawDiagnostics")
+ .files(testSource)
+ .outdir(".")
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ if (!expectedOutput.equals(actualOutput)) {
+ throw new AssertionError("Unexpected output: " + actualOutput);
+ }
+
+ actualOutput = new JavacTask(tb, Mode.CMDLINE)
+ .options("-XDrawDiagnostics",
+ "--module-path", testJar.toString())
+ .files(testSource)
+ .outdir(".")
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ if (!expectedOutput.equals(actualOutput)) {
+ throw new AssertionError("Unexpected output: " + actualOutput);
+ }
+
+ expectedOutput = Arrays.asList(
+ "- compiler.err.no.zipfs.for.archive: " + testJar.toString(),
+ "1 error"
+ );
+
+ actualOutput = new JavacTask(tb, Mode.CMDLINE)
+ .classpath()
+ .options("-XDrawDiagnostics",
+ "--module-path", testJar.getParent().toString())
+ .files(testSource)
+ .outdir(".")
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ if (!expectedOutput.equals(actualOutput)) {
+ throw new AssertionError("Unexpected output: " + actualOutput);
+ }
+ }
+
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg09.java Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 7020044 8062373
- *
- * @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
- * @author Maurizio Cimadamore
- * @compile/fail/ref=Neg09.out Neg09.java -source 8 -XDrawDiagnostics
- *
- */
-
-class Neg09 {
- class Member<X> {}
-
- static class Nested<X> {}
-
- void testSimple() {
- Member<?> m1 = new Member<>() {};
- Nested<?> m2 = new Nested<>() {};
- }
-
- void testQualified() {
- Member<?> m1 = this.new Member<>() {};
- Nested<?> m2 = new Neg09.Nested<>() {};
- }
-}
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg09.out Wed Jul 20 15:07:48 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-- compiler.warn.source.no.bootclasspath: 1.8
-Neg09.java:17:34: compiler.err.cant.apply.diamond.1: Neg09.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
-Neg09.java:18:34: compiler.err.cant.apply.diamond.1: Neg09.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
-Neg09.java:22:39: compiler.err.cant.apply.diamond.1: Neg09.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
-Neg09.java:23:40: compiler.err.cant.apply.diamond.1: Neg09.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
-4 errors
-1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09a.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7020044 8062373
+ *
+ * @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=Neg09a.out Neg09a.java -source 8 -XDrawDiagnostics
+ *
+ */
+
+class Neg09a {
+ class Member<X> {}
+
+ void testSimple() {
+ Member<?> m1 = new Member<>() {};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09a.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+- compiler.warn.source.no.bootclasspath: 1.8
+Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09b.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7020044 8062373
+ *
+ * @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=Neg09b.out Neg09b.java -source 8 -XDrawDiagnostics
+ *
+ */
+
+class Neg09b {
+
+ static class Nested<X> {}
+
+ void testSimple() {
+ Nested<?> m2 = new Nested<>() {};
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09b.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+- compiler.warn.source.no.bootclasspath: 1.8
+Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09c.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7020044 8062373
+ *
+ * @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=Neg09c.out Neg09c.java -source 8 -XDrawDiagnostics
+ *
+ */
+
+class Neg09c {
+ class Member<X> {}
+
+ void testQualified() {
+ Member<?> m1 = this.new Member<>() {};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09c.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+- compiler.warn.source.no.bootclasspath: 1.8
+Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09d.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7020044 8062373
+ *
+ * @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=Neg09d.out Neg09d.java -source 8 -XDrawDiagnostics
+ *
+ */
+
+class Neg09d {
+
+ static class Nested<X> {}
+
+ void testQualified() {
+ Nested<?> m2 = new Neg09.Nested<>() {};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg09d.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,4 @@
+- compiler.warn.source.no.bootclasspath: 1.8
+Neg09d.java:16:33: compiler.err.doesnt.exist: Neg09
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/AnachronisticModuleInfo/AnachronisticModuleInfoTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8157512
+ * @summary AssertionError in javac when module-info < v53.0
+ * @library /tools/lib
+ * @modules
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask module-info
+ * @run main AnachronisticModuleInfoTest
+ */
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class AnachronisticModuleInfoTest extends TestRunner {
+
+ protected ToolBox tb;
+
+ AnachronisticModuleInfoTest() {
+ super(System.err);
+ tb = new ToolBox();
+ }
+
+ public static void main(String... args) throws Exception {
+ AnachronisticModuleInfoTest t = new AnachronisticModuleInfoTest();
+ t.runTests();
+ }
+
+ /**
+ * Run all methods annotated with @Test, and throw an exception if any
+ * errors are reported..
+ *
+ * @throws Exception if any errors occurred
+ */
+ protected void runTests() throws Exception {
+ runTests(m -> new Object[] { Paths.get(m.getName()) });
+ }
+
+ Path[] findJavaFiles(Path... paths) throws IOException {
+ return tb.findJavaFiles(paths);
+ }
+
+ @Test
+ public void anachronisticModuleInfoTest(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "class C { }");
+ String modulePath = System.getProperty("test.classes");
+
+ String log = new JavacTask(tb, Task.Mode.CMDLINE)
+ .options("-XDrawDiagnostics",
+ "-upgrademodulepath", modulePath)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+ String expected = "- compiler.err.cant.access: foo.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.anachronistic.module.info: 52, 0))";
+ if (!log.contains(expected))
+ throw new Exception("expected output not found" + log);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/AnachronisticModuleInfo/module-info.jcod Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,38 @@
+class foo/module-info {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ class #6; // #1
+ Utf8 "SourceFile"; // #2
+ Utf8 "module-info.java"; // #3
+ Utf8 "Module"; // #4
+ Utf8 "java.base"; // #5
+ Utf8 "foo/module-info"; // #6
+ } // Constant Pool
+
+ 0x8000; // access
+ #1;// this_cpx
+ #0;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ } // methods
+
+ [] { // Attributes
+ Attr(#2) { // SourceFile
+ #3;
+ } // end SourceFile
+ ;
+ Attr(#4) { // Module
+ 0x0001000580000000;
+ 0x00000000;
+ } // end Module
+ } // Attributes
+} // end class foo/module-info
--- a/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -123,12 +123,17 @@
.files(findJavaFiles(src))
.run();
+ Path emptyClassPath = base.resolve("emptyClassPath");
+
+ Files.createDirectories(emptyClassPath);
+
// This is the test, to verify that the module being compiled will not be able to read
// modules on the module path when a --limit-modules is used
new TestCase(base)
.testOpts("--module-path", modules.toString(), "--limit-modules", "jdk.compiler")
.otherOpts("-XDrawDiagnostics",
- "--module-source-path", src.toString())
+ "--module-source-path", src.toString(),
+ "-classpath", emptyClassPath.toString())
.files(findJavaFiles(src))
.expect(Task.Expect.FAIL, "compiler.err.module.not.found")
.run();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/InvalidModuleDirective/module-info.java Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8157519
+ * @summary Error messages when compiling a malformed module-info.java confusing
+ * @compile/fail/ref=moduleinfo.out -XDrawDiagnostics module-info.java
+ */
+
+module java.transaction {
+ requires java.base;
+ resuires javax.interceptor.javax.interceptor.api;
+ requires public javax.enterprise.cdi.api;
+ requires public java.sql;
+ requires public java.rmi;
+ export javax.transaction;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/InvalidModuleDirective/moduleinfo.out Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,2 @@
+module-info.java:10:3: compiler.err.invalid.module.directive
+1 error
--- a/langtools/test/tools/javac/tree/TreePosTest.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/tree/TreePosTest.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -108,7 +108,7 @@
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util
- * @run main TreePosTest -q -r .
+ * @run main/othervm TreePosTest -q -r .
*/
public class TreePosTest {
/**
--- a/langtools/test/tools/javac/varargs/7043922/T7043922.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java Mon Aug 29 08:53:32 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.util
+ * @run main/othervm T7043922
*/
import com.sun.source.util.JavacTask;
--- a/langtools/test/tools/lib/toolbox/ModuleBuilder.java Wed Jul 20 15:07:48 2016 +0200
+++ b/langtools/test/tools/lib/toolbox/ModuleBuilder.java Mon Aug 29 08:53:32 2016 -0700
@@ -165,7 +165,7 @@
if (!comment.isEmpty()) {
sb.append("/**\n").append(comment.replace("\n", " *")).append(" */\n");
}
- sb.append("module ").append(name).append(" {");
+ sb.append("module ").append(name).append(" {\n");
requires.forEach(r -> sb.append(" " + r + "\n"));
exports.forEach(e -> sb.append(" " + e + "\n"));
uses.forEach(u -> sb.append(" " + u + "\n"));
--- a/make/common/Modules.gmk Wed Jul 20 15:07:48 2016 +0200
+++ b/make/common/Modules.gmk Mon Aug 29 08:53:32 2016 -0700
@@ -229,6 +229,7 @@
sub(/public/, ""); \
sub(/\/\/.*/, ""); \
sub(/\/\*.*\*\//, ""); \
+ gsub(/^ +\*.*/, ""); \
gsub(/ /, ""); \
printf(" %s", $$0) } \
END { printf("\n") }' $m \
--- a/nashorn/.hgtags Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/.hgtags Mon Aug 29 08:53:32 2016 -0700
@@ -365,3 +365,4 @@
68020a486500422e2c8b94b0f35cafe54c9e219a jdk-9+129
0de67a63e2c73781ecf5979a2f3aa9619a445c37 jdk-9+130
ee77c6b3713ab293e027ac3ea1cc16f86dac535f jdk-9+131
+55a75af751dfe44039baef2b762ee7347021025b jdk-9+132
--- a/nashorn/make/nbproject/nbjdk.properties Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/make/nbproject/nbjdk.properties Mon Aug 29 08:53:32 2016 -0700
@@ -20,5 +20,5 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-nbjdk.active=JDK_1.8
+nbjdk.active=JDK_9
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java Mon Aug 29 08:53:32 2016 -0700
@@ -34,6 +34,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URI;
@@ -50,6 +51,7 @@
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.tools.Shell;
@@ -157,6 +159,15 @@
global.addShellBuiltins();
+ // redefine readLine to use jline Console's readLine!
+ ScriptingFunctions.setReadLineHelper(str-> {
+ try {
+ return in.readLine(str);
+ } catch (final IOException ioExp) {
+ throw new UncheckedIOException(ioExp);
+ }
+ });
+
if (System.getSecurityManager() == null) {
final Consumer<String> evaluator = str -> {
// could be called from different thread (GUI), we need to handle Context set/reset
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Mon Aug 29 08:53:32 2016 -0700
@@ -474,6 +474,8 @@
return toPrimitive((ScriptObject)obj, hint);
} else if (isPrimitive(obj)) {
return obj;
+ } else if (hint == Number.class && obj instanceof Number) {
+ return ((Number) obj).doubleValue();
} else if (obj instanceof JSObject) {
return toPrimitive((JSObject)obj, hint);
} else if (obj instanceof StaticClass) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java Mon Aug 29 08:53:32 2016 -0700
@@ -42,6 +42,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
import jdk.nashorn.internal.objects.NativeArray;
import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
@@ -92,11 +94,7 @@
* @throws IOException if an exception occurs
*/
public static Object readLine(final Object self, final Object prompt) throws IOException {
- if (prompt != UNDEFINED) {
- System.out.print(JSType.toString(prompt));
- }
- final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- return reader.readLine();
+ return readLine(prompt);
}
/**
@@ -219,6 +217,30 @@
return outString;
}
+ // Implementation for pluggable "readLine" functionality
+ // Used by jjs interactive mode
+
+ private static Function<String, String> readLineHelper;
+
+ public static void setReadLineHelper(Function<String, String> func) {
+ readLineHelper = Objects.requireNonNull(func);
+ }
+
+ public static Function<String, String> getReadLineHelper() {
+ return readLineHelper;
+ }
+
+ public static String readLine(final Object prompt) throws IOException {
+ final String p = (prompt != UNDEFINED)? JSType.toString(prompt) : "";
+ if (readLineHelper != null) {
+ return readLineHelper.apply(p);
+ } else {
+ System.out.print(p);
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ return reader.readLine();
+ }
+ }
+
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
return MH.findStatic(MethodHandles.lookup(), ScriptingFunctions.class, name, MH.type(rtype, types));
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/ShellFunctions.java Wed Jul 20 15:07:48 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/ShellFunctions.java Mon Aug 29 08:53:32 2016 -0700
@@ -34,6 +34,7 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.objects.Global;
/**
@@ -66,11 +67,9 @@
public static Object input(final Object self, final Object endMarker, final Object prompt) throws IOException {
final String endMarkerStr = (endMarker != UNDEFINED)? JSType.toString(endMarker) : "";
final String promptStr = (prompt != UNDEFINED)? JSType.toString(prompt) : ">> ";
- final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
final StringBuilder buf = new StringBuilder();
while (true) {
- System.out.print(promptStr);
- final String line = reader.readLine();
+ final String line = ScriptingFunctions.readLine(promptStr);
if (line == null || line.equals(endMarkerStr)) {
break;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8163945.js Mon Aug 29 08:53:32 2016 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8163945: Honor Number type hint in toPrimitive on Numbers
+ *
+ * @test
+ * @run
+ */
+
+function assertLessThan(a, b) {
+ Assert.assertTrue(a < b);
+ Assert.assertTrue(a <= b);
+ Assert.assertFalse(a >= b);
+ Assert.assertFalse(a > b);
+}
+
+assertLessThan(new java.lang.Long(2), new java.lang.Long(10));
+assertLessThan(new java.lang.Long(2), 10);
+assertLessThan(2, new java.lang.Long(10));
+
+assertLessThan(new java.math.BigInteger(2), new java.math.BigInteger(10));
+assertLessThan(new java.math.BigInteger(2), 10);
+assertLessThan(2, new java.math.BigInteger(10));
+
+assertLessThan(new java.util.concurrent.atomic.AtomicInteger(2), new java.util.concurrent.atomic.AtomicInteger(10));
+assertLessThan(new java.util.concurrent.atomic.AtomicInteger(2), 10);
+assertLessThan(2, new java.util.concurrent.atomic.AtomicInteger(10));